Rails 5活动记录协会

问题描述:

我正在学习如何使用Ruby on Rails,并希望找到解决问题的最佳方法。我已经搜遍了很多论坛和Rails文档,但尚未能够理解解决方案,所以希望有人能够帮助!Rails 5活动记录协会

我的应用程序有3个控制器 - 用户,user_addresses和发票。每个用户可以有多个user_addresses,也可以有多个发票。我在我的发票表中添加了一个user_id列作为我的user_addresses表的主键和一个user_id和address_id列作为主键。

当我创建一个发票并选择一个地址分配给它,然后保存它,我想不出如何填充user_id和address_id,我只能得到一个或另一个来保存。在我下面的例子中,我得到了user_id来保存,但不知道如何从地址中获取user_id和id以保存到发票。

我用has_many:user_addresses和has_many:invoices设置了我的用户模型。我的发票和用户地址模型belongs_to:用户。从我读过的内容来看,我想我可能需要使用一个:扩展名,但我迷路了,不知道该怎么做。任何帮助或指导将不胜感激!

发票表格

<div class="form-group"> 
    <%= label_tag(:user_id, "Customer") %> 
    <%= f.select(:user_id, @addresses.map {|a| [a.user.first_name + ' ' + a.user.last_name + ' - ' + a.street_1, a.user.id]},{}, {:class => 'form-control'}) %> 
    </div> 

    <div class="form-check"> 
    <label class="form-check-label"> 
    <%= f.check_box(:status, :class => 'form-check-input') %> 
    Status 
    </label> 
    </div> 

    <div class="form-group"> 
    <%= label_tag(:service_date, "Service Date") %> 
    <%= f.text_field(:service_date, 'data-provide' => 'datepicker', :class => 'form-control') %> 
    </div> 

    <div class="form-group"> 
    <%= label_tag(:service_type, "Service Type") %> 
    <%= f.select(:service_type, ["General Pest", "Weed Control", "Specialty Pest", "Rodent"],{}, {:class => 'form-control'}) %> 
    </div> 

    <div class="form-group"> 
    <%= label_tag(:service_charge, "Service Charge") %> 
    <%= f.text_field(:service_charge, :class => 'form-control') %> 
    </div> 

发票控制器

def new 
    @invoice = Invoice.new 
    @addresses = UserAddress.all 
    end 

表发票

create_table "invoices", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t| 
t.integer "user_id" 
t.integer "address_id" 
t.boolean "status",   default: false 
t.string "service_date" 
t.string "service_type" 
t.string "service_areas" 
t.string "service_materials" 
t.string "service_charge" 
t.string "service_info" 
t.datetime "created_at",      null: false 
t.datetime "updated_at",      null: false 
t.index ["address_id"], name: "index_invoices_on_address_id", using: :btree 
t.index ["user_id"], name: "index_invoices_on_user_id", using: :btree 

+0

“我只能得到一个或另一个保存”是什么意思?即什么程序导致哪些行为(错误和/或输出)的输入?还请显示所有相关的代码和*阅读[mcve] s *。 PS请参阅我在答案开始处添加的修改。 – philipxy

我加了一个user_id列作为我user_addresses表

声明说PK说,用户最多只能有一个地址的主键。如果你想让一个用户能够拥有多个地址,那么你不需要这个PK。您可能希望每个用户地址对都是UNIQUE/PK。

USER_ID和ADDRESS_ID列在我的发票表的主键

这意味着你不能有两个发票为同一人 - 地址对。这可能不是你想要的。通常,发票的唯一候选/主键是唯一的运行时发票ID。虽然很可能你想某种索引帮助优化查找基于人地址对的发票。

如果你声明一些列作为候选键(可能是PK),那么你就是说它们是唯一的而不是NULL。但是你说你想要一张没有用户和地址的发票,这与此相矛盾。每个用户有许多发票,但仅限于每个用户有多个用户地址对(每个都有一张发票)。声明这样一个有一张发票。而不是用户所做的,因为您必须保持UserInvoice与发票同步冗余。 (但真的要发票ID)

答:通过管理冗余。包括解决上述索引优化问题。

阅读有关首先制作关系设计,然后通过Active Record设计表达它(以及所需的优化)的内容。

+0

感谢您的回复。我可能没有彻底解释,但我确实希望所有发票都有一个user_id和address_id ...但由于用户可以有多个地址,我不知道如何设置关系来自动填充基于数据库的选择。我将通过Active Record做更多关于关系设计的研究。我找到了一个解决方案,通过在设置为地址标识的选择字段选项上设置data-attr并使用jQuery来填充隐藏表单元素的值,以将地址标识提交给表单。 – StevenHolder

+0

我没有说发票没有关联的user_id和address_id。我说你可能想要那些不构成发票的CK,你可能想要一个列的invoice_id。 – philipxy