ARTLoe
ARTLoe

Reputation: 1799

Rails scope not displaying correct information - Rails 4

I would just like to understand rails scopes. Any good explanation would be helpful.

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

Answers (1)

spickermann
spickermann

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

Related Questions