我的Profile
可以是published
。 profile
belongs_to :user
和has_many :ratings
。
User has_one :profile
has_many :ratings
和Rating belongs_to :profile && belongs_to :user
。
A Profile.rb
。
这些是上述模型的模式:
# == Schema Information
#
# Table name: profiles
#
# id :integer not null, primary key
# first_name :string
# last_name :string
# created_at :datetime not null
# updated_at :datetime not null
# user_id :integer
:
User.rb
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# email :string default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
# first_name :string
# last_name :string
:
Rating.rb
# == Schema Information
#
# Table name: ratings
#
# id :integer not null, primary key
# speed :integer default(0)
# passing :integer default(0)
# tackling :integer default(0)
# dribbling :integer default(0)
# profile_id :integer
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
coach = User.find(7)
请注意>p = Profile.published.where(id: coach.ratings.order(passing: :desc).pluck(:profile_id))
(0.4ms) SELECT "ratings"."profile_id" FROM "ratings" WHERE "ratings"."user_id" = $1 ORDER BY "ratings"."passing" DESC [["user_id", 7]]
Profile Load (1.1ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."status" = $1 AND "profiles"."id" IN (52, 14, 24, 29) [["status", 1]]
> p.ids
=> [24, 14, 52]
。
当我执行此查询时:
profile.ids
请注意p.ids
生成的> coach.ratings.order(passing: :desc).limit(3).pluck(:profile_id)
(0.8ms) SELECT "ratings"."profile_id" FROM "ratings" WHERE "ratings"."user_id" = $1 ORDER BY "ratings"."passing" DESC LIMIT $2 [["user_id", 7], ["LIMIT", 3]]
=> [52, 14, 24]
的顺序。
但是,当我只是自己运行内部查询时,我会得到一个不同的顺序:
[19] pry(main)> cids = coach.ratings.order(passing: :desc).limit(3).pluck(:profile_id)
(0.7ms) SELECT "ratings"."profile_id" FROM "ratings" WHERE "ratings"."user_id" = $1 ORDER BY "ratings"."passing" DESC LIMIT $2 [["user_id", 7], ["LIMIT", 3]]
=> [52, 14, 24]
[21] pry(main)> q = Profile.published.where(id: cids)
Profile Load (0.7ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."status" = $1 AND "profiles"."id" IN (52, 14, 24) [["status", 1]]
[22] pry(main)> q.ids
=> [24, 14, 52]
导致这种差异的原因是什么,为什么我不能得到第一个查询以始终产生我对后一个查询所期望的相同结果?
修改1
请注意,即使我在第一个查询中对ID的顺序进行硬编码,它仍然会按原始顺序返回结果:
joins
修改2
当我尝试以下profiles
查询时,它会返回违反published
状态的status: :unpublished
(当它不应该返回时,会返回> a = Profile.joins(:ratings).where(status: :published, id: coach.ratings.pluck(:profile_id)).order('ratings.passing DESC')
(0.4ms) SELECT "ratings"."profile_id" FROM "ratings" WHERE "ratings"."user_id" = $1 [["user_id", 7]]
Profile Load (1.8ms) SELECT "profiles".* FROM "profiles" INNER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE "profiles"."status" = $1 AND "profiles"."id" IN (24, 52, 29, 14) ORDER BY ratings.passing DESC [["status", 1]]
> o = Profile.find(29)
Profile Load (0.8ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."id" = $1 LIMIT $2 [["id", 29], ["LIMIT", 1]]
[59] pry(main)> o.status
=> "unpublished"
> a.ids
=> [52, 14, 24, 14, 24]
的个人资料):< / p>
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ... AND "profiles"."id" IN (24, 52, 29, 14) ORDER BY ratings.pa...
^
: SELECT DISTINCT "profiles".* FROM "profiles" INNER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE "profiles"."status" = $1 AND "profiles"."id" IN (24, 52, 29, 14) ORDER BY ratings.passing DESC
编辑3
来自上述查询的服务器出错:
@profiles
编辑3a
当我尝试从错误页面的REPL访问>> @profiles
!! #<ActiveRecord::StatementInvalid: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ... AND "profiles"."id" IN (24, 52, 29, 14) ORDER BY ratings.pa...
^
: SELECT DISTINCT "profiles".* FROM "profiles" INNER JOIN "ratings" ON "ratings"."profile_id" = "profiles"."id" WHERE "profiles"."status" = $1 AND "profiles"."id" IN (24, 52, 29, 14) ORDER BY ratings.passing DESC>
>>
时,这就是我得到的:
application/x-www-form-urlencoded
答案 0 :(得分:2)
原因是where
查询不会根据输入的顺序返回记录。因此where
内的ID排序不会影响结果。如果您想在p
中订购记录,则应在order
查询后链接where
。试试这个:
Profile.published.joins(:ratings).where(id: coach.ratings.pluck(:profile_id)).order('ratings.speed')
按OP编辑
所以原因是正确的,但修复不正确。
我终于通过另一种方式问这个问题找到了解决方案,I got an answer。但为了完整起见,我在这里添加答案:
Profile.published
.joins(:ratings)
.where(ratings: { user_id: coach.id } )
.order('ratings.passing')
答案 1 :(得分:2)
第一个查询的顺序不确定将第一个查询的结果用作选择器的第二个查询的顺序。选择并不意味着订购。
用你的例子来解释:
coach_rating_profile_ids = coach.ratings.pluck(:profile_id)
profiles = Profile.where(id: coach_rating_profile_ids)
coach_rating_profile_ids
中的ID可以是任何顺序,并且不会影响所选Profile
个对象的排序。您可以轻松地尝试coach_rating_profile_ids
的排序来查看。例如:
profiles = Profile.where(id: coach_rating_profile_ids.reverse)
将给出相同的结果(假设没有发生其他交易)。
如果要在所选的“个人档案”集中设置特定顺序,则必须在其上使用明确的.order()
(而不是id
选择器上)。例如:
profiles = Profile.where(id: coach_rating_profile_ids).order(xxxx)
其中xxxx
是某种排序标准。