Rails 4 并在 'has_many' SQL 中引用父 ID
Rails 4 and referencing parent id in 'has_many' SQL
TL;DR: 如何在 has_many SQL 子句中使用相应父对象的 ID 来查找子对象?
长版:
我有以下示例代码:
class Person < AR::Base
has_many :purchases, -> {
"SELECT * from purchases
WHERE purchase.seller_id = #{id}
OR purchase.buyer_id = #{id}"
}
这是从 Rails 3 迁移过来的,看起来像
has_many :purchases, :finder_sql => proc { #same SQL as above# }
我想在一个关联中找到与一个 Person 对象相关联的所有购买,无论这个人是销售对象还是购买对象。
更新: 我更正了SQL,它是反的。对不起!另外:关联只需要是只读的:我永远不会使用这个关联创建记录,所以使用 id
两次应该没问题。但是我 do 希望能够在其上链接其他范围,例如@person.purchases.paid.last_5
,所以在一个方法中创建两个关联的总和是行不通的(至少在 Rails 3 中行不通),因为它不是 return 和 AM::Relation但是一个简单的数组。
在 Rails 4.2 中使用上述定义时,我得到
> Person.first.purchases
undefined method `id' for #<Person::ActiveRecord_Relation:0x...>
错误很明显,但是我该如何解决呢?
由于这只是用于表达 has_many 关系的更复杂 SQL 代码的示例(例如,为了性能而使用子选择的多个 JOINS),问题是:
如何在 has_many SQL 子句中使用父对象的 ID?
我认为您的代码根本行不通。您正在定义与两个外键的关联...这意味着如果您想从当前 Purchase
创建一个新的 Person
,将使用什么外键,seller_id
或 buyer_id
?那只是没有意义。
无论如何,您得到的错误很清楚:您正在调用一个变量 id
,它未在 SQL 代码的块上下文中初始化。
我从您的问题中了解到,解决该问题的更好方法是按以下方式使用关联,然后定义一种方法,为您提供产品所具有的所有人,包括买家和卖家。像这样:
class Purchase < ActiveRecord::Base
belongs_to :buyer, class_name: 'Person'
belongs_to :seller, class_name: 'Person'
def persons
ids = (buyer_ids + seller_ids).uniq
Person.where(ids: id)
end
end
class Person < ActiveRecord::Base
has_many :sold_purchases, class_name: 'Purchase', foreign_key: 'buyer_id'
has_many :buyed_purchases, class_name: 'Purchase', foreign_key: 'seller_id'
end
我的方法是,buyer_id
和 seller_id
是购买的属性,而不是人的属性。
可能是我理解的不正确,请指正。
TL;DR: 如何在 has_many SQL 子句中使用相应父对象的 ID 来查找子对象?
长版: 我有以下示例代码:
class Person < AR::Base
has_many :purchases, -> {
"SELECT * from purchases
WHERE purchase.seller_id = #{id}
OR purchase.buyer_id = #{id}"
}
这是从 Rails 3 迁移过来的,看起来像
has_many :purchases, :finder_sql => proc { #same SQL as above# }
我想在一个关联中找到与一个 Person 对象相关联的所有购买,无论这个人是销售对象还是购买对象。
更新: 我更正了SQL,它是反的。对不起!另外:关联只需要是只读的:我永远不会使用这个关联创建记录,所以使用 id
两次应该没问题。但是我 do 希望能够在其上链接其他范围,例如@person.purchases.paid.last_5
,所以在一个方法中创建两个关联的总和是行不通的(至少在 Rails 3 中行不通),因为它不是 return 和 AM::Relation但是一个简单的数组。
在 Rails 4.2 中使用上述定义时,我得到
> Person.first.purchases
undefined method `id' for #<Person::ActiveRecord_Relation:0x...>
错误很明显,但是我该如何解决呢?
由于这只是用于表达 has_many 关系的更复杂 SQL 代码的示例(例如,为了性能而使用子选择的多个 JOINS),问题是:
如何在 has_many SQL 子句中使用父对象的 ID?
我认为您的代码根本行不通。您正在定义与两个外键的关联...这意味着如果您想从当前 Purchase
创建一个新的 Person
,将使用什么外键,seller_id
或 buyer_id
?那只是没有意义。
无论如何,您得到的错误很清楚:您正在调用一个变量 id
,它未在 SQL 代码的块上下文中初始化。
我从您的问题中了解到,解决该问题的更好方法是按以下方式使用关联,然后定义一种方法,为您提供产品所具有的所有人,包括买家和卖家。像这样:
class Purchase < ActiveRecord::Base
belongs_to :buyer, class_name: 'Person'
belongs_to :seller, class_name: 'Person'
def persons
ids = (buyer_ids + seller_ids).uniq
Person.where(ids: id)
end
end
class Person < ActiveRecord::Base
has_many :sold_purchases, class_name: 'Purchase', foreign_key: 'buyer_id'
has_many :buyed_purchases, class_name: 'Purchase', foreign_key: 'seller_id'
end
我的方法是,buyer_id
和 seller_id
是购买的属性,而不是人的属性。
可能是我理解的不正确,请指正。