Neil Neil - 11 months ago 77
Ruby Question

Rails scopes with hash syntax

Here are my two models:

class Author < ApplicationRecord
has_many :articles

class Article < ApplicationRecord
belongs_to :author
scope :articles_by_author, ->(author_id) {joins(:author).where(author: {id: author_id})}

I am trying to get the
scope to work. Basically: It should return all the articles for a particular Author.

Here is what happens:

First I grab an author:

author = Author.first

Then I run the query:


The generated SQL seems right:

SELECT "articles".*
FROM "articles"
INNER JOIN "authors"
ON "authors"."id" = "articles"."author_id"
WHERE "author"."id" = 1

But it errors out with the following:

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: SELECT "articles".* FROM "articles" INNER JOIN "authors" ON "authors"."id" = "articles"."author_id" WHERE "author"."id" = 1

What am I messing up within this scope? I want to keep the hash syntax within this scope.

Answer Source

In joins/includes you can use model names, but in where clause you should use database table name, thus plural authors:

scope :articles_by_author, lambda { |author_id|
  joins(:author).where(authors: { id: author_id })

P.S. I've styled your code a bit to meet (Rubocop's) conventions :)

P.P.S. Isn't it easier (having that we know author_id) to just go with:

Author.find(author_id).articles # ? :)