activerecord铲运营商<<

时间:2017-03-01 17:18:20

标签: ruby-on-rails ruby activerecord

来自联系人控制器内部的编辑操作...

@programs << @contact.program

产生以下错误:

NoMethodError - undefined method `<<' for Program::ActiveRecord_Relation

联系人型号:

belongs_to :program

程序模型:

has_many :contacts
validates :name, presence: true, uniqueness: true

@programs.class
Program::ActiveRecord_Relation

@contact.program.class
Program(id: integer, name: string, active: boolean, created_at: datetime, updated_at: datetime)

问题:为什么此操作失败?为什么记录不能添加到记录集合中。是什么阻止了集合(ActiveRecord_Relation)添加记录?

2 个答案:

答案 0 :(得分:1)

你在这里自相矛盾:

Program has_many contacts vs Programs << Contact.program

如果您尝试将Contact添加到特定程序,则会考虑添加联系人:

program.contacts << contact

如果您正在尝试为联系人设置程序:

contact.program = program
然而,没有意义的是试图在“程序”中添加一些东西,这不是一种关系。由于您已将has_many :programs定义为此系统,因此@programs.<<无法对关系采取任何行动。

答案 1 :(得分:0)

您收到此错误是因为ActiveRecord::Relation类只是ActiveRecord查询返回的结果集合。您可能通过运行Program.where或类似查询来获得它。它不是ActiveRecord::Association,因此您无法向其添加更多记录。

您必须改为使用父对象返回的关联。

以下是您正在做的事情的一个例子,与您应该做的事情相比:

class User < ApplicationRecord
    has_many :programs
end

class Program < ApplicationRecord
    belongs_to :user
end

new_program = Program.new

# What you're attempting.
programs_where = Program.where(user_id: User.first) # Class is Program::ActiveRecord_Relation
programs_where << new_program # Throws Error b/c << is not available on ActiveRecord::Relation objects.

# What you should be attempting.
user = User.first
programs_assoc = user.programs # Returns Programs::ActiveRecord_Associations_CollectionProxy
programs_assoc << new_program # Returns Correctly

注意:不清楚@programs是如何定义的。这个答案对你不起作用,请提供完整的控制器代码,以及你正在使用的其他型号。