生成主键而不创建记录

时间:2012-05-17 20:52:09

标签: sql ruby-on-rails sequel

我希望能够做一些像

这样的事情
@foo = MyClass.new
5.times do
  @foo.things.build
end

但我的 @foo 需要有一个主键才能正常工作,Soo在不创建对象的情况下生成主键的最佳方法是什么?

这样做的目的是能够更轻松地使用嵌套表单

form_builder.fields_for :things do ...

2 个答案:

答案 0 :(得分:1)

您可能想要的是NestedAttributes

嵌套属性允许您通过父级保存关联记录的属性。默认情况下,嵌套属性更新已关闭,您可以使用accepts_nested_attributes_for class method启用它。启用嵌套属性时,将在模型上定义属性编写器。

每个ORM的实现都不同,这里是续集 ActiveRecord

注意:完整教程也可在Nerdgem

获得

续集强制

想象一下,有一个Project类有很多任务

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的依赖

您可以在plugin site

上找到非常好的文档
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"}>]

保存项目时,它将保存项目和任务。

如果您甚至可以同时编辑许多任务。

ActiveRecord实施

以下是如何使用它。

想象一下,有一个Project类有很多任务

Project.rb

class Project < ActiveRecord::Base
  attr_accessible :title
  has_many :tasks
  accepts_nested_attributes_for :tasks
end

Task.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"}]

注意:还有一个Railscast可以帮助您使用嵌套表单。 Orginal RailscastRevised Railscast

答案 1 :(得分:1)

我认为OP正在询问如何初始化视图操作属性,以便在标准Rails资源的 new 操作中使用。此时,主父母没有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

新的控制器操作:

@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

还有一个名为nested_form的好宝石,由Ryan Bates编写(https://github.com/ryanb/nested_form),它可以帮助你完成其余的CRUD操作。