StatementInvalid Rails Query - PullRequest
       2

StatementInvalid Rails Query

0 голосов
/ 31 мая 2018

У меня работает следующий запрос:

jobs = current_location.jobs.includes(:customer).all.where(complete: complete)

Однако, когда я добавляю предложение where для запроса имени таблицы клиента, я получаю сообщение об ошибке.

jobs = current_location.jobs.includes(:customer).all.where(complete: complete).where("customers.fist_name = ?", "Bob")

Вот ошибка:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "customers"
LINE 1: ...bs"."complete" = $2 AND "jobs"."status" = $3 AND (customers....
                                                         ^
: SELECT  "jobs".* FROM "jobs" INNER JOIN "jobs_users" ON "jobs"."id" = "jobs_users"."job_id" WHERE "jobs_users"."user_id" = $1 AND "jobs"."complete" = $2 AND "jobs"."status" = $3 AND (customers.last_name = 'Bob') ORDER BY "jobs"."start" DESC LIMIT $4 OFFSET $5

Метод current_location:

def current_location
    return current_user.locations.find_by(id: cookies[:current_location])
end

Модель местоположения

has_many :jobs
has_and_belongs_to_many :customers

Модель задания

belongs_to :location
belongs_to :customer

Модель клиента

has_many :jobs
has_and_belongs_to_many :locations

Как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

includes присоединится к таблице, только если вы установили ссылку на ассоциацию.

При использовании includes вы обеспечите ссылку на ассоциацию в 2 модах:

  • Вы можете использовать метод references, он присоединится к таблице независимо от того, есть ли какие-либо условия запроса (если вы ДОЛЖНЫ использовать необработанный SQL, как показано в вашем вопросе, тогда этот метод вам нужно будет использовать), например

    current_location.jobs
      .includes(:customer)
      .references(:customer)
    
  • Или вы можете использовать версию поиска хеша where: (Обратите внимание, что при использовании ассоциативной ссылки в предложении where вы должны ссылаться на имя таблицы, в данном случаеcustomers, а не имя ассоциации customer)

    current_location.jobs
      .includes(:customer)
      .where(customers: {first_name: "Bob" }) 
    

Оба из них будут загружать customer для jobs, на который ссылаются.

Первый параметр (references) будет ВНЕШНЕЕ ПРИСОЕДИНЯТЬСЯ к таблице customers, так что все задания загружаются, даже если у них нет клиентов, если условия запроса не ссылаются на таблицу customers.

Второй вариант (с использованием where) будет ВНЕШНЕЕ СОЕДИНИТЬ с таблицей клиентов, но с учетом параметра запроса к таблице клиентов он будет очень похож на ВНУТРЕННЕЕ СОЕДИНЕНИЕ.

Если вам нужно толькодля поиска jobs на основе customer информации, тогда joins будет лучшим выбором, поскольку это создаст ВНУТРЕННЕЕ СОЕДИНЕНИЕ с таблицей клиентов, но не будет пытаться загрузить какие-либо данные о клиентах в запросе, например,

current_location.jobs.joins(:customer).where(customers: {first_name: "Bob" }) 

joins всегда будет включать связанную таблицу независимо от ссылки в запросе.

Sidenote: all в обоих ваших запросах совершенно не требуется

0 голосов
/ 31 мая 2018

includes(:customer) не обязательно объединяет таблицу клиентов в запрос SQL.Вам нужно использовать joins(:customer), чтобы заставить Rails присоединить таблицу customers к запросу SQL и сделать ее доступной для условий запроса.

jobs = current_location.jobs
                       .joins(:customer)
                       .includes(:customer)
                       .where(complete: complete)
                       .where(customers: { first_name: 'Bob' })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...