Ошибка: при запросе к таблицам со многими связями в рельсах - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь открыть модальное окно, в котором должен отображаться пользователь с ролью «игрок». Я реализовал три таблицы: роль пользователя и роль пользователя, где есть пользователь и роль, имеет множество через ассоциацию с таблицей пользователей.

условие следующее: один пользователь может быть игроком или администратором или и тем, и другим, при отображении мы должны отображать пользователей с ролью, только игрок.

схема

 create_table "roles", force: :cascade do |t|
    t.string "name"
    t.boolean "active"
    t.integer "counter"
 end
  create_table "user_roles", force: :cascade do |t|
    t.integer "role_id"
    t.integer "user_id"
    t.index ["role_id"], name: "index_user_roles_on_role_id"
    t.index ["user_id"], name: "index_user_roles_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "first_name"
    t.string "last_name"
    t.string "email"
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
    t.index ["team_id"], name: "index_users_on_team_id"
  end

модель стола имеет видследует

class User < ApplicationRecord
  has_many :user_roles
  has_many :roles, through: :user_roles, :dependent => :destroy
end
class UserRole < ApplicationRecord
  belongs_to :role
  belongs_to :user
  validates :user_id, :uniqueness => { :scope => :role_id }
end

class Role < ApplicationRecord
    has_many :user_roles
    has_many :users, through: :user_roles ,:dependent => :destroy   
end

в командном контроллере у меня есть

def load_users
              @user = User.includes(:userroles).where('userroles.name = ?',"Player")

                respond_to do |format|
                  format.html
                  format.js
                  format.json
                end

            end

журнал показывает следующую ошибку

Ошибка (SQLite3 :: SQLException: нет такого столбца: userroles.name: ВЫБЕРИТЕ "users". * ИЗ "users" WHERE (userroles.name = 'Player')):

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Вам нужно, чтобы имена таблиц соответствовали:

Неправильно:

User.includes(:userroles).where("userroles.name = ?","Player")

Справа (с подчеркиванием)

User.includes(:user_roles).where("user_roles.name = ?","Player")

Добавление (Я сейчас не на моей машине разработчика, так что это не проверено)

User.joins(:user_roles).where("user_roles.name = ?", "Player")
0 голосов
/ 18 февраля 2019

По умолчанию includes не выполняет left join и выполняет вместо этого два отдельных запроса к БД.Вы можете легко заставить left join, но в этом случае достаточно сделать:

@user = User.includes(:user_roles).where(user_roles: { name: 'Player' })

Используя нотацию user_roles: { }, вы дадите ActiveRecord знать, что вы хотите запрашивать БД также по столбцу user_roles и ActiveRecordрешает выполнить left join.Если у вас нет условия, легко переводимого в эту нотацию, вы можете форсировать left join, используя eager_load:

@user = User.eager_load(:user_roles).where('some complex SQL query including user_roles column(s)')
...