Active Record Nested Attributes
通过嵌套属性(nested attribute),你可以通过parent来保存与其相关联的属性。默认情况下,嵌套属性是关闭的,你可以开启accepts_nested_attributes_for这个类方法,就在该model上生成一个属性writer。
属性writer是以该关联命名。例如,为你的model增加两个新方法:
author_attributes=(attributes) 和 pages_attributes=(attributes).
class Book < ActiveRecord::Base
has_one :author
has_many :pages
accepts_nested_attributes_for :author, :pages
end
使用了accepts_nested_attributes_for的每一个关联都自动开启:autosave
一对一关联
一个Member有一个Avatar
class Member < ActiveRecord::Base
has_one :avatar
accepts_nested_attributes_for :avatar
end
开启一对一关联的嵌套属性可以通过这样方法一次性创建Member:
params = { :member => { :name => 'Jack', :avatar_attributes => { :icon => 'smiling' } } }
member = Member.create(params[:member])
member.avatar.id # => 2
member.avatar.icon # => 'smiling'
也可以这样update avatar
params = { :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 => true
end
此时,如果向属性hash里增加一个_destroy的key,并且value是true,则该关联model将被删除。
member.avatar_attributes = { :id => '2', :_destroy => '1' }
member.avatar.marked_for_destruction? # => true
member.save
member.reload.avatar # => nil
注意这里,只有当parent被保存后,关联的model才真正被删除。
一对多关联
一个member有一些post
class Member < ActiveRecord::Base
has_many :posts
accepts_nested_attributes_for :posts
end
你可通过属性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 # => 2
member.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? }
end
params = { :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 # => 2
member.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 => true
end
params = { :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.save
member.reload.posts.length # => 1
保存
所有对model修改的行为,包括标记将要销毁,会随着parent被保存原子性的被自动保存或者删除。这些开始与parent的save方法,发生在其内部的事务里。详见 Active Record Autosave Association
使用attr_accessible
使用attr_accessible如果不小心,可能会干扰到嵌套属性的使用。例如,上述member model如下使用attr_accessible:
attr_accessible :name
你需要这样的修改:
attr_accessible :name, :posts_attributes
验证parent model 的存在
如果你想验证一个child记录是否和一个parent记录关联,你可以使用validates_presence_of和inverse_of:
class Member < ActiveRecord::Base
has_many :posts, :inverse_of => :member
accepts_nested_attributes_for :posts
end
class Post < ActiveRecord::Base
belongs_to :member, :inverse_of => :posts
validates_presence_of :member
end
具体应用见 http://cn.asciicasts.com/episodes/196-nested-model-form-part-1
分享到:
相关推荐
nestive, 一个更好的Rails 嵌套可以继承布局插件 Nestive 用于 Rails的嵌套布局帮助器Nestive为你的Rails 应用程序添加强大的布局和视图助手。 它类似于嵌套布局技术,已经在 Rails 指南中记录,并且在许多其他嵌套...
我想在父模型的错误中使用本地化来重命名嵌套的多态属性。 例子 用户模型 地址模型,多态 雇主模式 用户有一个邮寄地址,多态地址 用户有一个雇主 用户验证username 、 email 、 mailing_address和employer的...
使用Vanilla JS的Rails动态嵌套表单 类似于茧,但没有jquery依赖! 安装 只需将其添加到您的gemfile gem 'vanilla_nested' # or gem 'vanilla_nested', github: 'arielj/vanilla-nested' 如果您使用的是Sprockets...
它的外观和感觉完全类似于但是使用了jQuery Nested Sortable和或而不是Nestable和Ancestry 。 与和awesome_nested_set一起使用。 奖励功能: 对带有rails_admin_toggleable的已enabled列的特殊情况支持 cover和...
使用Rails构建可伸缩和可维护API的最佳方法
当我们执行FactoryGirl.attributes_for(:factory_name)时,FactoryGirl不提供嵌套属性,但是当我们以活动管理员形式测试控制器时,通常我们需要这些嵌套属性,这通常是通过对请求后的请求进行硬编码来实现的累。...
rails-settings, 使用 Ruby on Rails 管理设置 Rails的设置 ruby gem,通过在单独的数据库表中将它们存储为序列化的哈希来处理。 包含命名空间和默认值。要求ruby 1.9.3或者更高版本Rails 3.1或者更高版本( 包括 ...
当我们需要在 rails 中创建嵌套表单时,我们使用了nested_form gem。 但是如果你使用 AngularJS 作为前端,那么你就不能使用它。 当您希望嵌套表单使用 AngularJS 时,您需要编写自己的代码。 在这个应用程序中,我...
嵌套套 Go Nested Set是的实现。 该项目是的Go版本,它使用相同的数据结构设计,因此它与一起使用相同的数据。 实际上,原始设计就是为此而设计的,由我们的Rails应用程序中的管理的内容,还需要维护前端Go API。 这...
Ember 嵌套 Rails ##Configure Rails 生成 ember-esque json # config/initializers/active_model_serializer.rb ActiveModel :: Serializer . setup do | config | config . embed = :ids config . embed_in_...
使用Aptana+Rails开发Rails Web应用 有Aptana的安装配置等等,中文
使用RSpec 测试Rails 程序.pdf
rails, Ruby on Rails 欢迎使用 RailsRails 是一个web应用程序框架,它包括根据 Model-View-Controller ( MVC ) Pattern 创建数据库备份的web应用程序所需的所有内容。理解 MVC Pattern 是理解 Rai
它使用jQuery动态添加和删除嵌套关联。 适用于任意深度嵌套的关联(经过4个级别的测试)。 可与诸如类的表单构建器。 需要Ruby 1.9+和Rails资产管道。安装将此行添加到您的应用程序的Gemfile中: gem 'nested_form_...
蒙古样嵌套集 Mongoid嵌套集是Mongoid的嵌套集模式的实现。...要开始使用Mongoid嵌套集合,只是声明acts_as_nested_set您的手机型号: class Category include Mongoid::Document acts_as_nested
rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails ...
这是一个在Rails应用程序中使用React并使用webpack的示例
在过去的几年中,《Ruby on Rails Tutorial》这本书被视为介绍使用 Rails 进行 Web 开发的先驱者。 在这个全球互联的世界中,计算机编程和 Web 应用程序开发都在迅猛发展,我很期待能为中国的开发者提供 Ruby on ...
《Rails之道》按照Rails的各个子系统进行组织编排,分别介绍了Rails的环境、初始过程、配置和日志记录,Rails的分配器、控制器... 《Rails之道》是Rails的权威参考书,适合对Rails已经有一定了解的开发人员学习和使用。
[Pragmatic Bookshelf] Crafting Rails Applications Expert Practices for Everyday Rails Development (E-Book) ☆ 图书概要:☆ Rails 3 is a huge step forward. You can now easily extend the framework, ...