这是我的schema
create_table "duties", force: :cascade do |t|
t.string "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.boolean "is_general", default: false
t.boolean "write_all", default: true
end
create_table "duties_users", force: :cascade do |t|
t.bigint "duty_id"
t.bigint "user_id"
t.boolean "has_write_access", default: true
t.index ["duty_id"], name: "index_duties_users_on_duty_id"
t.index ["user_id"], name: "index_duties_users_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "mail"
t.text "password_digest"
t.datetime "birth_date"
t.boolean "is_admin", default: false
t.integer "rating", default: 0
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "name", default: ""
t.string "surname", default: ""
t.string "patronymic", default: ""
t.datetime "restore_date", default: "2021-02-11 09:57:14"
t.boolean "is_boss", default: false
end
我的连接模型
class DutyUser < ApplicationRecord
self.table_name = "duties_users"
belongs_to :user
belongs_to :duty
end
用户模型class User < ApplicationRecord
has_secure_password
has_many :duties_users, class_name: "DutyUser"
has_many :duties, through: :duties_users, class_name: "Duty"
end
和责任模型
class Duty < ApplicationRecord
has_many :duties_users, class_name: "DutyUser"
has_many :users, through: :duties_users, class_name: "User"
end
我想找到所有对特定任务有写权限的用户。为了实现它,我需要使用这样的东西:
Duty.first.duties_users.find_all{|m| m.has_write_access}.map{|m| m.user}
如何简化这行代码?
这里的要点是:
- Dutyhas_manyusers。所以如果你有
duty
,你也可以做duty.users
这样你就能得到所谓的" ActiveRecord relationship " 中的用户 - ActiveRecord Relations的行为很像数组,除了它们只允许您访问一个模型的实例(在本例中是duty)。users将返回一个充满User实例的关系),它允许您运行进一步的查询,以及User上的任何类方法。请注意,与数组不同,关系实际上不包含任何内容。它悄悄地构建一些SQL,只有当你强迫它(例如通过迭代它与
.each
,或要求.count
)发送SQL到数据库 - 查询可以使用
where
方法完成-例如.where(has_write_access: true)
-这是在数据库中完成的,所以它非常快。