我希望能够做类似的事情
@foo = MyClass.new
5.times do
@foo.things.build
end
但是我的@foo需要有一个主键才能工作,所以在不创建对象的情况下生成主键的最佳方法是什么?
这样做的目的是能够更轻松地使用嵌套表单
form_builder.fields_for :things do ...
我希望能够做类似的事情
@foo = MyClass.new
5.times do
@foo.things.build
end
但是我的@foo需要有一个主键才能工作,所以在不创建对象的情况下生成主键的最佳方法是什么?
这样做的目的是能够更轻松地使用嵌套表单
form_builder.fields_for :things do ...
我相信 OP 正在询问如何初始化视图操作属性以用于标准 Rails 资源的新操作。此时,主父级没有 ID。解决方案很简单:
该模型:
class ParentObject < ActiveRecord::Base
# the child model in this example is called child_objects
has_many :child_objects, :dependent => :destroy
accepts_nested_attributes_for :child_objects
new 的控制器操作:
@object = Object.new :example_field => "my field"
@object.child_objects.build :name => "value_1" # pretending that name is a field
@object.child_objects.build :name => "value_2"
然后,在视图中:
= form_for(@object) do |f| # top level Object
= f.label :example_field
= f.text_field :example_field
=# the next line loops twice in this example
= f.fields_for :child_objects do |child|
= child.label :name
= child.text_field :name
还有一个由 Ryan Bates (https://github.com/ryanb/nested_form) 编写的名为nested_form 的很好的 gem,它可以帮助您完成其余的 CRUD 操作。
您可能想要的是NestedAttributes
嵌套属性允许您通过父项将属性保存在关联记录上。默认情况下,嵌套属性更新是关闭的,您可以使用accepts_nested_attributes_for class method
. 当您启用嵌套属性时,会在模型上定义一个属性编写器。
每个 ORM 的实现都不同,这里是sequel和ActiveRecord
注意: Nerdgem也提供完整教程
想象有一个项目类有很多任务
class Project < Sequel::Model
one_to_many :tasks
end
class Task < Sequel::Model
many_to_one :project
end
要启用嵌套属性,您需要为 Project 类包含两个插件
Sequel::Plugins::NestedAttributes: 允许您通过调用当前对象的方法直接创建、更新和删除关联对象。嵌套属性是使用 nested_attributes 类方法定义的:
Sequel::Plugins::InstanceHooks:是 NestedAttributes 的依赖
您可以在插件站点上找到非常好的文档
Project.plugin :instance_hooks
Project.plugin :nested_attributes
完成后,您可以nested_attributes
在所需的类上调用该方法
Project.nested_attributes :tasks
现在你可以这样做
p = Project.new(:title=>'Project')
p.tasks_attributes = [{:title=>'First Task'}, {:title=>'Second Task'}]
puts p.tasks.inspect
# It will output this
# [#<Task @values={:title=>"First Task"}>, #<Task @values={:title=>"Second Task"}>]
保存项目时,它将同时保存项目和任务。
如果您甚至可以同时编辑许多任务。
以下是如何使用它。
想象有一个项目类有很多任务
项目.rb
class Project < ActiveRecord::Base
attr_accessible :title
has_many :tasks
accepts_nested_attributes_for :tasks
end
任务.rb
class Tasks < ActiveRecord::Base
attr_accessible :title, :project_id
belongs_to :project
end
现在你可以这样做了。
p = Project.new
p.tasks_attributes=[{title: "First Task"}]
p.things
# Would output this
#=> [#<Thing id: nil, title: "First Task", created_at: nil, updated_at: nil, bar_id: nil>]
p.save
保存项目时,它将同时保存项目和任务。
如果您想同时编辑多个项目任务,您可以这样做
p.tasks_attributes=[{title: "First Task"},{title: "Second Task"}]
注意:还有一个 Railscasts 可以帮助您处理嵌套表单。原始 Railscast ,修订 Railscast