我在" Rails"中找出如何做到这一点有点困难。如果它甚至可能的话。
背景:我有一个模型客户端,其has_many
关系称为:users_and_managers
,其定义如下:
has_many :users_and_managers, -> do
Spree::User.joins(:roles).where( {spree_roles: {name: ["manager", "client"]}})
end, class_name: "Spree::User"
模型Users
有一个名为has_many
的{{1}}关系,它只是一个简单的credit_cards
- has_many
关系(它在框架中定义)。
简而言之,belongs_to
目标:我想获取属于此客户的用户创建的所有信用卡(如上述关系中所定义)。
问题:我认为我可以使用clients ---has many---> users ---has many---> credit_cards
来实现这一点,我这样定义:
has_many ... :through
不幸的是,这与使用角色表的连接产生了错误:
SQLite3 :: SQLException:没有这样的列:spree_roles.name :
SELECT" spree_credit_cards"。*
FROM" spree_credit_cards"
INNER JOIN" spree_users" ON" spree_credit_cards"。" user_id" =" spree_users"。" id"
WHERE" spree_users"。" client_id" = 9 AND" spree_roles"。" name" IN('经理','客户')
(重点和格式化我的)
正如您在生成的查询中看到的那样,Rails似乎忽略了我在has_many :credit_cards, through: :users_and_managers
块中定义的查询的join(:roles)
部分,同时仍然保留了where子句部分。
当前解决方案:当然,我可以通过定义一个简单的方法来解决问题:
:users_and_managers
但我觉得必须有更简洁的方法来做这件事,而且我对错误信息的来源感到困惑。
问题:有谁知道为什么AR / Rails似乎是"选择性"关于它将在查询中包含哪些AR方法,以及如何使用def credit_cards
Spree::CreditCard.where(user_id: self.users_and_managers.joins(:credit_cards))
end
关系为该客户的所有用户和管理者获取信用卡集合,假设它是可能的?
答案 0 :(得分:1)
joins(:roles)
被忽略,因为无法将ActiveRecord::Relation
附加到class Spree::Role < ActiveRecord::Base
scope :clients_and_managers, -> { where(name: %w{client manager}) }
# a better scope name would be nice :)
end
class Client < ActiveRecord::Base
has_many :users,
class_name: "Spree::User",
foreign_key: :client_id
has_many :clients_and_managers_roles,
-> { merge(Spree::Role.clients_and_managers) },
through: :users,
source: :roles
has_many :clients_and_managers_credit_cards,
-> { joins(:clients_and_managers_roles) },
through: :users,
source: :credit_cards
end
。您需要在块中使用直接AR方法。另外,让我们稍微清理一下:
client = # find client according to your criteria
credit_card_ids = Client.
clients_and_managers_credit_cards.
where(clients: {id: client.id}).
pluck("DISTINCT spree_credit_cards.id")
credit_cards = Spree::CreditCard.where(id: credit_card_ids)
使用该设置,您应该能够执行以下操作:
class Spree::CreditCard < ActiveRecord::Base
belongs_to :user # with Spree::User conditions, if necessary
end
credit_cards = Spree::CreditCard.
where(spree_users: {id: client.id}).
joins(user: :roles).
merge(Spree::Role.clients_and_managers)
如您所见,该查询数据库两次。要查询一次,请查看以下内容:
{{1}}