Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 是否有一个“问题”;第一个“U或“U构建”;方法上有许多关联?_Ruby On Rails_Activerecord_Associations - Fatal编程技术网

Ruby on rails 是否有一个“问题”;第一个“U或“U构建”;方法上有许多关联?

Ruby on rails 是否有一个“问题”;第一个“U或“U构建”;方法上有许多关联?,ruby-on-rails,activerecord,associations,Ruby On Rails,Activerecord,Associations,在rails 3.2+中,您可以执行以下操作: SomeModel.some_scope.first_or_initialize 这意味着您还可以: OtherModel.some_models.first_or_initialize 我觉得这非常有用,但是我想在我的上有一个first\u或\u build方法,它有许多关联,这就像first\u或\u initialize一样,但在需要时也会像build那样向关联添加一条新记录 更新澄清:是的,我知道第一次\u或\u初始化和第一次\u或\u

在rails 3.2+中,您可以执行以下操作:

SomeModel.some_scope.first_or_initialize
这意味着您还可以:

OtherModel.some_models.first_or_initialize
我觉得这非常有用,但是我想在我的
上有一个
first\u或\u build
方法,它有许多关联,这就像
first\u或\u initialize
一样,但在需要时也会像
build
那样向关联添加一条新记录

更新澄清:是的,我知道
第一次\u或\u初始化
第一次\u或\u创建
。问题是,
first\u或\u initialize
不会像
build
那样将初始化的记录添加到关联的目标中,
first\u或\u create
。。。好。。。创建一个记录,这不是目的

我有一个使用关联扩展的解决方案:

class OtherModel < ActiveRecord::Base

  has_many :some_models do 
    def first_or_build( attributes = {}, options = {}, &block )
      object = first_or_initialize( attributes, options, &block )
      proxy_association.add_to_target( object ) if object.new_record?
      object
    end
  end

end
class-OtherModel
我只是想知道:

  • 这个问题的内置解决方案已经存在了吗
  • 我的实现有我看不到的缺陷
我不确定rails中是否有任何内置的东西能够完全满足您的需要,但是您可以使用比当前使用的更简洁的扩展来模拟第一个\u或\u初始化代码,我相信它可以满足您的需要,并将其包装成可重用的扩展,如下面所示。这是用Rails 3.2扩展格式编写的

module FirstOrBuild
  def first_or_build(attributes = nil, options = {}, &block)
    first || build(attributes, options, &block)
  end
end

class OtherModel < ActiveRecord::Base
  has_many :some_models, :extend => FirstOrBuild
end
modulefirstorbuild
def first_或_build(属性=nil,选项={},&block)
第一个| |构建(属性、选项和块)
结束
结束
类OtherModelFirstOrBuild
结束

如果您想在
其他型号上执行即时加载程序,该怎么办?某些型号在某个时候执行?我宁愿在初始化
回调之后在
中执行这样的初始化,我认为这是一种更干净的方法。非常正确。我不知道为什么我会这样做,这显然更好。为了让它在Rails 4.1.0.beta中工作,我必须在作用域上下文中指定代理关联;这样扩展名将读取
first | | scoping{proxy_association.build(attributes,&block)}
(任何地方都没有选项),调用看起来像
Post.first.comments.where(foo:'bar')。first_或_build
。我还使用了新语法has_many:posts,->{extensing FirstOrBuild}on Post。)@ChrisKeele感谢您的更新。当您执行诸如
foo.bar.where(标题:“buzz”).first\u或\u build
之类的操作时,这是否仍能正常工作?(也就是说,foo.bar中添加了一个新的酒吧,标题为“buzz”)。另外,我注意到first_或_create也没有将记录添加到代理_关联的目标中。也许我应该向rails团队提交一张罚单,API的当前状态没有遵循最小意外值的原则。IMHO
foo.bar.where(title:'buzz')。first_或_build(desc:'baz')
仍然通过
title
查找,如果存在,则使用预期的
title
desc
创建一个记录,并将
添加到
foo
的集合中。我使用的是Rails 3.2.17,我不得不使用@ChrisKeele的代码(这就像一个符咒)。其他人读到这篇文章就知道了——公认的答案对Rails 3.2的某些版本不起作用。