反向关联(inverse_of)在 has_many 中起作用吗?

5

我使用 has_one 时完美运行,但在 has_many 上不起作用。在这里,您可以看到 object_id 不同,因为它再次运行了另一个 SQL 以重新获取它。

ruby-1.9.2-p290 :001 > e = Employee.create(name: 'rafael', active: false)
ruby-1.9.2-p290 :002 > b = Badge.create(number: 1, employee: e)
ruby-1.9.2-p290 :003 > a = Address.create(street: "123 Market St", city: "San Diego", employee: e)
ruby-1.9.2-p290 :004 > e = Employee.first
  Employee Load (0.2ms)  SELECT "employees".* FROM "employees" LIMIT 1
 => #<Employee id: 1, name: "rafael", active: false, created_at: "2011-10-04 17:09:25", updated_at: "2011-10-04 17:09:25"> 
ruby-1.9.2-p290 :002 > e.is_active?
 => false 
ruby-1.9.2-p290 :003 > e.object_id
 => 2182895380 
ruby-1.9.2-p290 :004 > e.badge.employee.is_active?
  Badge Load (17.6ms)  SELECT "badges".* FROM "badges" WHERE "badges"."employee_id" = 1 LIMIT 1
 => false 
ruby-1.9.2-p290 :005 > e.badge.employee.object_id
 => 2182895380 
ruby-1.9.2-p290 :006 > e.addresses.first.employee.is_active?
  Address Load (0.2ms)  SELECT "addresses".* FROM "addresses" WHERE "addresses"."employee_id" = 1 LIMIT 1
  Employee Load (0.3ms)  SELECT "employees".* FROM "employees" WHERE "employees"."id" = 1 LIMIT 1
 => false 
ruby-1.9.2-p290 :007 > e.addresses.first.employee.object_id
  Address Load (0.3ms)  SELECT "addresses".* FROM "addresses" WHERE "addresses"."employee_id" = 1 LIMIT 1
  Employee Load (0.2ms)  SELECT "employees".* FROM "employees" WHERE "employees"."id" = 1 LIMIT 1
 => 2181302220 
ruby-1.9.2-p290 :008 >

这是我用来设置我的测试的代码:

class Employee < ActiveRecord::Base
  has_many :addresses, :inverse_of => :employee
  has_one :badge, :inverse_of => :employee

  accepts_nested_attributes_for :addresses
  accepts_nested_attributes_for :badge
  # validates_associated :addresses

  def is_active?
    active
  end
end

class Address < ActiveRecord::Base
  belongs_to :employee, :inverse_of => :addresses

  validates :city, length: { within: 100..1000, message: "Too short"}, :if => lambda {|a| a.employee.is_active?}
end

class Badge < ActiveRecord::Base
  belongs_to :employee, :inverse_of => :badge

  validates :number, length: { within: 2..10, message: "Too long"}, :if => lambda {|b| b.employee.is_active?}
end

3个回答

5

不是这样的。根据 Rails指南

  • 它们不能与:through关联一起使用。
  • 它们不能与:polymorphic关联一起使用。
  • 它们不能与:as关联一起使用。
  • 对于belongs_to关联,has_many反向关联会被忽略。

4

是的,我发现这些文档特别令人困惑。示例中给出了has_many :traps, inverse_of: :dungeon,但在下一段中又指出:对于belongs_to关联,has_many反向关联将被忽略 - davetapley
Naoyoshi的回答是正确的。这个答案要么过时了,要么是错误的。 - JackyJohnson

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接