我有一个数据模型的多对多关系设置,它处理成员和地址的问题域。基本上,“会员”可以有多个“地址”,就像有工作地址和家庭住址一样。
除了外键属性之外,我想在连接表上存储其他属性并保存数据。网上有很多关于多对多关系的例子,但是我没有找到关于存储额外数据的细节/例子。
这是我遇到的问题。
模型设置为:
模型
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
Address类中的'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'用于标记与成员关联的地址类型(aka;“home”或“work”)
正在更新此字段,这是我遇到的问题。
控制器&amp;图
member_controller设置模型如:
members_controller.rb
def new
@member = Member.new
@member.addresses.build #pre-build the associated address
end
然后,会员页面新操作的视图为
&lt;%= form_for @member do | m | %GT;
<%= 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 />
&lt;%end%&gt;
我的想法是,使用成员模型上的'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',用于携带我的附加内容数据
现在如何将数据导入关系或连接表?在 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
正如您在创建中所看到的,我正在尝试填充连接表上的数据,然后再次强制保存,以便保存与其他属性的关系或关联。
这不起作用,和/或我做错了。
任何建议都会受到最高的赞赏。
答案 0 :(得分:1)
尝试将模型更改为以下内容:
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和Addresses。
这两个RailsCasts也值得一看
答案 1 :(得分:0)
Rails不像我想的那样流利,但研究表明这可能会有效:
而不是
@member.member_addresses.first.address_type = @addr_type
尝试
@member.member_addresses.create(:address_type => @addr_type)