在多对多关系中加入表属性更新
我有一个处理成员和地址问题域的数据模型的多对多关系设置。基本上,一个'会员'可以有多个'地址',就像你有工作地址和家庭住址一样。在多对多关系中加入表属性更新
我想在连接表上存储其他属性并保存除外键属性以外的数据。网络上有很多关于多对多关系的例子,但是我没有找到关于存储额外数据的细节/例子。
这是我坚持的问题。
的模型设置为:
模式
class Member < ActiveRecord::Base
has_many :member_addresses
has_many :addresses, :through => :member_addresses
end
class MemberAddress < ActiveRecord::Base
belongs_to :address # foreign key for address -> address_id
belongs_to :member # foreign key for member ->member_id
end
class Address < ActiveRecord::Base
has_many :member_addresses
has_many :members, :through => :member_addresses
accepts_nested_attributes_for :members, :allow_destroy => true
end
的 'accepts_nested_attributes' 的地址类是嵌套形式。
数据库架构/迁移 的表(简化为张贴)是在连接表定义为
create_table "addresses", :force => true do |t|
t.string "firstline"
t.string "state"
....
end
create_table "member", :force => true do |t|
t.string "name"
....
end
create_table "member_addresses", :force => true do |t|
t.integer "member_id"
t.integer "address_id"
t.string "address_type"
end
字段“address_type”被用于标记,其与相关联的地址的类型该成员(又名;“家”或“工作”)
它正在更新此字段,我卡住了。
控制器&查看
的member_controller设置的模式,如:
members_controller.rb
def new
@member = Member.new
@member.addresses.build #pre-build the associated address
end
然后为会员页面视图新行动
<%=的form_for @成员do | m | %>
<%= m.label :first_name, "First Name"%>
<%= m.text_field :first_name %>
</p>
<%= m.fields_for :addresses do |addrform|%>
<%= addrform.label :firstline %>
<%= addrform.text_field :firstline %>
<% end %>
<br />
<%= label_tag 'Type of address' %>
<%= text_field_tag 'addrtype' %>
<br />
<%= m.submit "Add" %><br />
<%结束%>
的想法是,与上会员模式“accepts_nested_attributes”我可以进入表单上的数据在名称和地址属性添加。附加label_tag是被张贴了,我想存储
所以当形式在后的数据被填充(形成陷阱)地址类型数据的模样:
{"utf8"=>"✓",
"authenticity_token"=>"E0R038rcdJmBGjjxQ9nQLHGVbzM4ejA0vsEaIvqkwkE=",
"member"=>{"first_name"=>"James",
"last_name"=>"SMith",
"addresses_attributes"=>{"0"=>{"firstline"=>"this is the first line"}}},
"addrtype"=>"home",
"commit"=>"Add"}
所有优秀的 - 我得到我会员数据和地址数据,以及附加字段“ADDRTYPE”,这是用于承载我的附加数据
现在如何获取数据到relati在或加入表格?在member_controller创建行动
def create
# create a member with the params posted
@member = Member.new(params[:member])
# get data for 'relation data'
@addr_type = params[:addrtype]
if @member.save!
#update the relation now created with the address type
@member.member_addresses.first.address_type = @addr_type
# save the relationship (is this necessary?)
@member.save!
redirect_to members_path
end
正如你可以在看到创建我试图填补数据上的连接表,然后强制再次保存,这样的关系或协会与附加属性被保存。
这不起作用,和/或我做错了。
任何建议将不胜感激。
尝试改变你的模型,如下所示:
class Member < ActiveRecord::Base
has_many :member_addresses
accepts_nested_attributes_for :member_addresses, :allow_destroy => true
end
class MemberAddress < ActiveRecord::Base
belongs_to :member
has_many :addresses
accepts_nested_attributes_for :addresses, allow_destroy => true
end
class Address < ActiveRecord::Base
belongs_to :member_addresses
end
,改变你的member_controller.create方法
@member = Member.new(params[:member])
这应该允许您通过MemberController.create方法创建MemberAddresses和地址。
这2个RailsCasts也可能是值得一看
还不如精通Rails的,我想是,但研究表明,可能这可能工作:
而不是
@member.member_addresses.first.address_type = @addr_type
尝试
@member.member_addresses.create(:address_type => @addr_type)
正确的 - 它的工作原理提供了@member保存第一否则你得到的ActiveRecord :: RecordNotSaved:您不能调用创建,除非parent保存 –
唯一的问题是,如果有一个@ member.save!,必须保存父项,那么在MemberAddresses连接表中创建的两个记录中会创建额外的“创建”结果;一个用于第一次保存,它具有两个外键,一个用于具有address_type字段和成员对象的ID的“创建”。它缺少address_id字段 –