我有两个活动记录类,用户和用户技能。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 指定不同的别名?
我想我的问题与这个问题非常相似,但是由于我使用的是循环,我认为我不能使用建议的解决方案!
编辑:我也在 squeel github 上找到了这个,但不确定如何将它应用到我的特定用例中:需要一种方法来为同一关系上的多个连接设置别名连接
最后编辑:
我在 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