0

I have a Profile that can be published. A profile belongs_to :user and has_many :ratings.

A User has_one :profile, and has_many :ratings.

A Rating belongs_to :profile && belongs_to :user.

These are the schemas for the above models:

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
#

What I want to do is to find all the profiles, ranked by 1 rating attribute....e.g. all published profiles ranked by passing (highest to lowest).

I tried something like this:

Profile.published.where(id: coach.ratings.order(passing: :desc).pluck(:profile_id))

But that doesn't always give me the profiles in the order I expect.

So how do I do this query that allows me to get these profiles ranked by all of those ratings accordingly?

Edit 1

Please Note The key thing here is that I need to find the ratings on a profile left by a specific user.

In my query above, coach = User.find(7).

So each User leaves a bunch of ratings on many profiles.

What I want to do is filter all the profiles, that have a specific rating (say speed) and order those profiles, by the speed rating from highest to lowest (but this is user specific).

marcamillion
  • 32,933
  • 55
  • 189
  • 380
  • Correct me if I'm wrong. I see your logic seem conflic. Rating(profile_id, user_id). It means relationship User-Profile is n-n. But you set relationship profile-user is 1-1 before. – Duyet Nguyen Dec 23 '16 at 09:13
  • User-to-Profile is 1-1, Rating-to-Profile is n-n. How did you get User-Profile being n-n? The only that could be true is if I set a `has_many ratings_users through: :ratings`, no? – marcamillion Dec 23 '16 at 09:16
  • `User-Rating 1-n`, `Profile-Rating 1-n` => `User-Profile n-n` – Duyet Nguyen Dec 23 '16 at 09:19
  • Ahh interesting. So what's the solution you think? Isn't `User-Profile n-n` if only `thru Rating`? – marcamillion Dec 23 '16 at 09:20
  • I see `profiles` and `users` is the same. User has more only one field `email`. Could you use only 1 table `users` and remove table `profiles`? – Duyet Nguyen Dec 23 '16 at 09:25
  • Nope...they are two different things. Each user can have only 1 profile, but each user doesn't HAVE to have a profile and each profile doesn't HAVE to belong to a user. – marcamillion Dec 23 '16 at 09:26

1 Answers1

2

Use a join:

Profile.published
  .joins(:ratings)
  .where(ratings: { user_id: coach.id } )
  .order('ratings.passing')
Arjan
  • 6,264
  • 2
  • 26
  • 42
  • How do I find the ratings per the associated user? `coach` is a user in my original query. See the updated question to get more clarity on what I am looking for. – marcamillion Dec 23 '16 at 09:28
  • Bro....wow...perfect. That's exactly what I was looking for. Works like a charm. So simple and clean. Can't believe I never thought about that `where(ratings:...)`. – marcamillion Dec 23 '16 at 09:39