我已经看到了一些问题的答案,这些问题解决了如何在ActiveRecord关联中使用范围块,包括将对象本身传递到块中,如... ...
class Patron < ActiveRecord::Base
has_many :bars,
->(patron) { baz: patron.blah },
foreign_key: :somekey,
primary_key: :somekey
end
class Bar < ActiveRecord::Base
belongs_to :patron,
->(bar) { blah: bar.baz },
foreign_key: :somekey,
primary_key: :somekey
end
这里使用显式PK和FK是由于底层表之间的遗留关系。生产系统中有数以亿计的“顾客”。
作为澄清点@TJR - Patron和Bar之间的关系实际上是字段上的复合外键:somekey和:baz(或者反向的blah)。 ActiveRecord:foreign_key选项不允许使用数组。
我发现不幸的是,这会阻止后续的has_many:tos按预期工作。
class Patron < ActiveRecord::Base
has_many :bars,
->(patron) { baz: patron.blah },
foreign_key: :somekey,
primary_key: :somekey
has_many :drinks, through: :bars
end
使用直通关联会产生错误,如...
引发ArgumentError: 错误的参数数量(0表示1)
bar和drink之间的关联是经典的has_many,带有标准的外键和主键(bar_id,id)。
我想出了一些丑陋的工作,让我能够完成所需的功能,但整个事情闻起来很糟糕。到目前为止,其中最好的看起来像
class Patron < ActiveRecord::Base
has_many :bars,
->(patron) { baz: patron.blah },
foreign_key: :somekey,
primary_key: :somekey
def drinks
bars.drinks
end
end
我已收到现有的Bar类,它包含数亿条记录,正如我之前提到的那样,使数据库方面的改变变得困难。
有些帖子似乎建议在proc中进行动态字符串评估,以避免传递当前的顾客对象 - 但正如其他帖子所述,这不起作用。
请告诉我如何让has_many通过关系工作。
答案 0 :(得分:0)
我刚刚在Rails 4.2中尝试过这种关联。它运作得很好:
class Patron < ActiveRecord::Base
has_many :bars,
->(patron) { where(baz: patron.blah) },
foreign_key: :patron_id,
primary_key: :id
has_many :drinks, through: :bars
end
class Bar < ActiveRecord::Base
belongs_to :patron,
->(bar) { where(blah: bar.baz) },
foreign_key: :patron_id,
primary_key: :id
has_many :drinks
end
class Drink < ActiveRecord::Base
end
检查关联:
> p1 = Patron.first
> p1.drinks
Drink Load (0.8ms) SELECT "drinks".* FROM "drinks" INNER JOIN "bars" ON "drinks"."bar_id" = "bars"."id" WHERE "bars"."patron_id" = 1 AND "bars"."baz" = 1 [["patron_id", 1], ["baz", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Drink id: 3, name: "drink 3", bar_id: 2, created_at: "2017-04-07 03:30:06", updated_at: "2017-04-07 03:30:06">]>