首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

【译】rails的嵌套属性(Nested Attributes)应用

2012-09-19 
【译】rails的嵌套属性(Nested Attributes)使用? class Book ActiveRecord::Basehas_one :author has_many

【译】rails的嵌套属性(Nested Attributes)使用

?

 class Book < ActiveRecord::Basehas_one :author has_many :pages  accepts_nested_attributes_for :author, :pagesend
?使用了accepts_nested_attributes_for的每一个关联都自动开启:autosave
class Member < ActiveRecord::Base  has_one :avatar  accepts_nested_attributes_for :avatarend
?开启一对一关联的嵌套属性可以通过这样方法一次性创建Member:

?

params = { :member => { :name => 'Jack', :avatar_attributes => { :icon => 'smiling' } } }member = Member.create(params[:member])member.avatar.id # => 2member.avatar.icon # => 'smiling'也可以这样update avatarparams = { :member => { :avatar_attributes => { :id => '2', :icon => 'sad' } } }member.update_attributes params[:member]member.avatar.icon # => 'sad'
?默认情况下你只能设置或更新关联的model。如果你想通过属性hash来删除关联model,你需要使用:allow_destroy 选项
class Member < ActiveRecord::Base  has_one :avatar  accepts_nested_attributes_for :avatar, :allow_destroy => trueend
?此时,如果向属性hash里增加一个_destroy的key,并且value是true,则该关联model将被删除。
member.avatar_attributes = { :id => '2', :_destroy => '1' }member.avatar.marked_for_destruction? # => truemember.savemember.reload.avatar # => nil
?注意这里,只有当parent被保存后,关联的model才真正被删除。
class Member < ActiveRecord::Base  has_many :posts  accepts_nested_attributes_for :postsend
?你可通过属性hash来增加或更新关联post model每一个不含有id键的新记录会被实例化,除非该hash也包含了一个 :_destroy => true
params = {   :member => {    :name => 'joe', :posts_attributes => [      { :title => 'Kari, the awesome Ruby documentation browser!' },      { :title => 'The egalitarian assumption of the modern citizen' },      { :title => '', :_destroy => '1' } # 该记录会被忽略    ]  }}member = Member.create(params['member'])member.posts.length # => 2member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
?通过 :reject_if proc 设置忽略的不满足条件的记录。例如:
class Member < ActiveRecord::Base   has_many :posts   accepts_nested_attributes_for :posts, :reject_if => proc { |attributes| attributes['title'].blank? } endparams = { :member => {  :name => 'joe', :posts_attributes => [    { :title => 'Kari, the awesome Ruby documentation browser!' },    { :title => 'The egalitarian assumption of the modern citizen' },    { :title => '' } #  这个记录会被忽略  ]}}member = Member.create(params['member'])member.posts.length # => 2member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
?:reject_if 也可一接受一个symbol来代表一个可用方法:如果hash中含有一个id和已有的关联记录相匹配,则被匹配到的记录会被修改:
member.attributes = {  :name => 'Joe',  :posts_attributes => [    { :id => 1, :title => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },    { :id => 2, :title => '[UPDATED] other post' }  ]}member.posts.first.title # => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!'member.posts.second.title # => '[UPDATED] other post'
?默认关联记录是被保护的(不被删除)。如果想通过属性hash来删除任何关联记录,你需要打开:allow_destroy选项, 这样使用_destroy键来删除记录就行:
class Member < ActiveRecord::Base  has_many :posts  accepts_nested_attributes_for :posts, :allow_destroy => trueendparams = { :member => {  :posts_attributes => [{ :id => '2', :_destroy => '1' }]}}member.attributes = params['member']member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true  标记将被删除member.posts.length # => 2  未保存,所以还没删除member.savemember.reload.posts.length # => 1 
?
attr_accessible :name
?你需要这样的修改:
attr_accessible :name, :posts_attributes
?
class Member < ActiveRecord::Base  has_many :posts, :inverse_of => :member  accepts_nested_attributes_for :postsendclass Post < ActiveRecord::Base  belongs_to :member, :inverse_of => :posts  validates_presence_of :memberend
?
具体应用见 http://cn.asciicasts.com/episodes/196-nested-model-form-part-1

?

?

热点排行