我目前有这个可怕的书面查询:
membership_ids = User.where(skip_membership_renewal: true).includes(:memberships).map(&:membership_ids).flatten
Memberships.where(id: membership_ids)
我一直在尝试使用joins
,以便我可以进行一次查询。
Membership.includes(:user).where("user.skip_membership_renewal", true)
但是,由于我不断收到错误,因此无法正常工作:ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR
。
我的关系是:
User has_many :memberships
Membership belongs_to :user
我做错了什么?
答案 0 :(得分:0)
您可以使用:
Membership.where(:user => User.skip_membership_renewal)
将范围添加到用户...
def self.skip_membership_renewal
where(skip_membership_renewal: true)
end
您应该会发现它作为单个查询运行。
答案 1 :(得分:0)
你只是有一个复数错误。在Rails中,您将模型定义为单数(load(using:)
),数据库表是复数(User
)。
users
也就是说,您不需要使用SQL文字来处理这种简单的情况。还有许多其他方法来组合此查询,例如David Aldridge建议的范围选项,或者其中之一:
Membership.includes(:user).where("users.skip_membership_renewal" => true)
更重要的是,它们只对大多数适配器执行单个SQL查询,因为它们使用子查询:
non_renewing_users = User.where(skip_membership_renewal: true)
Membership.joins(:user).merge(non_renewing_users)
Membership.where(user: non_renewing_users)