Reputation: 1799
I would just like to understand rails scopes. Any good explanation would be helpful.
I used a scope to try and display this:
scope :resumes_with_employments, -> {
where("id in (select resume_id from employments)")
}
I have 2 users. They both have a resume with employments but yet only one user is being displayed.
models
user.rb
has_one :resume
resume.rb
belongs_to :user
has_many :employments
employment.rb
belongs_to :resume
schema
create_table "users", force: true do |t|
t.string "email",
t.string "firstname"
t.string "lastname"
t.string "city"
end
create_table "resumes", force: true do |t|
t.string "address"
t.string "postcode"
t.text "summary"
t.integer "user_id"
end
create_table "employments", force: true do |t|
t.string "companyname"
t.date "datestart"
t.date "dateend"
t.integer "resume_id"
t.string "employer_name"
t.string "employer_tel"
t.string "employer_address"
t.string "employer_location"
t.string "employer_city"
t.string "employer_postcode"
t.string "employer_email"
end
Upvotes: 1
Views: 38
Reputation: 106882
scope :resumes_with_employments, -> {
where("id in (select resume_id from employments)")
}
would scope the query to users which have an id
that matches a resume_id
from the employments
table. Since the resume_id
has nothing to do with the user's id
this scope doesn't return useful results.
I would use joins
in this case, because it translates to a INNER JOIN
in SQL:
# in models/user.rb
scope :resumes_with_employments, -> { joins(resume: :employments) }
The nested INNER JOIN
ensures that only users are return that have a resume that has at least one employment. Since resumes might have multiple employments and the nature of INNER JOIN
you will need to use uniq
to exclude duplicates like this:
User.resumes_with_employments.uniq
Or when you want to count uniq users with that scope:
User.resumes_with_employments.distinct.count(:id)
Upvotes: 2