简体   繁体   中英

Error: while querying a tables with has many through relationship in rails

I am trying to pop up a modal which should display the user with role "player", I implemented three tables user role and userrole where user and role has, has many through association by userrole table.

the condition is as follows one user can be a player or admin or both, while displaying we should display users with the role, player only.

schema

 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

the table model is as follows

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

in team controller i have

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

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

            end

log shows following error

Error (SQLite3::SQLException: no such column: userroles.name: SELECT "users".* FROM "users" WHERE (userroles.name = 'Player')):

By default, includes doesn't perform left join and performs two separate DB queries instead. You can easily force left join though, in this case it's enough to do:

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

By using user_roles: { } notation you let ActiveRecord know that you want to query DB also by user_roles column and ActiveRecord decides to perform left join . If you don't have the condition easily translatable to this notation, you can force left join using eager_load :

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

You need to keep your table names consistent:

Wrong:

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

Right (with underscore)

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

Addendum (I'm not not on my dev machine right now, so this is untested)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM