【发布时间】:2013-12-22 13:07:54
【问题描述】:
我有两个活动记录类,用户和用户技能。 UserSkill有一个squeel sifter,如下图:
class User < ActiveRecord::Base
has_many :user_skills
end
和
class UserSkill < ActiveRecord::Base
belongs_to :user
belongs_to :skill
sifter :with_skill_id_and_value_of_at_least do |params|
if params[1].present?
skill_id.eq(params[0]) & value.gteq(params[1])
else
skill_id.eq(params[0])
end
end
end
我现在正在执行搜索,并且在控制器中有这个:
def search
users = User.skip_user(current_user)
if params[:user_skills].present?
params[:user_skills].each do |user_skill|
#user_skill is an array where [0] is the id, and [1] the minimum value.
#if [1] is empty, it will default to 0 in the sifter
users = users.joins(:user_skills).where do
{
user_skills: sift(:with_skill_id_and_value_of_at_least, user_skill)
}
end
end
end
end
我的问题是,基本上,当应用关系时,我最终得到以下 sql:
SELECT "users".* FROM "users"
INNER JOIN "user_skills" ON "user_skills"."user_id" = "users"."id"
WHERE "user_skills"."skill_id" = 10
AND (("user_skills"."skill_id" = 11 AND "user_skills"."value" >= 2))
这不是我想要的:
确实,我希望用户的 user_skill 的技能 ID 为 10,并且用户技能的技能 ID 为 11 且值高于 2。
ActiveRecords 似乎“链接”了条件,我总是以空关系结束,因为 UserSkill 不能同时具有 10 和 11 的 id!
我想以某种方式区分第一个条件和第二个条件,以便我让具有 user_skills 的用户按顺序满足第一个条件和第二个条件,而不是相同的 user_skill 行,我不确定如何做到这一点!
我认为别名将是可行的方法,但我如何使用 squeel 或 ActiveRecord 语法为要引用的每个 user_skill 指定不同的别名?
我想我的问题与this one 非常相似,但是由于我使用的是循环,我认为我不能使用建议的解决方案!
编辑:我也在 squeel github 上找到了这个,但不确定如何将其应用于我的特定用例:Need a way to alias joins for multiple joins on the same relation
最后编辑:
我已经用 sql 写了一个可行的解决方案,但是你可以看到它非常难看:
params[:user_skills].each_with_index do |user_skill,index|
users = users.joins(",user_skills as u#{index}")
.where("u#{index}.skill_id= ? AND u#{index}.value >= ?"
,user_skill[0].to_i, user_skill[1].to_i)
end
【问题讨论】:
标签: ruby-on-rails activerecord join postgresql-9.1 squeel