所以我有这些表:
<mat-table [dataSource]="dataSource">
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let project">{{project.name}}</mat-cell>
</ng-container>
<ng-container matColumnDef="key">
<mat-header-cell *matHeaderCellDef> Key </mat-header-cell>
<mat-cell *matCellDef="let project">{{project.Key}}</mat-cell>
</ng-container>
<ng-container matColumnDef="reason">
<mat-header-cell *matHeaderCellDef> reason </mat-header-cell>
<mat-cell *matCellDef="let project">{{project.reason}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; column: displayedColumns;"></mat-row>
</mat-table>
我这样做了,当我打电话给Room.find(1)。用户我得到了房间里所有用户的清单。但是,我还希望能够调用类似Room.find(1).admins的内容并获取管理员用户列表(其中,room_users中的is_admin为true)。我该怎么办?
感谢您的时间!
答案 0 :(得分:0)
您可以在proc
关系中定义has_many
来设置SQL子句,例如ORDER
或WHERE
:
# room.rb
has_many :rooms_users, class_name: 'RoomsUser'
has_many :users, through: :rooms_users
has_many :admins,
proc { where(rooms_users: { is_admin: true }) },
through: :rooms_users,
class_name: 'User',
source: :users
# user.rb
has_many :administrated_rooms,
proc { where(rooms_users: { is_admin: true }) },
through: :rooms_users,
class_name: 'Room',
source: :rooms
您可以使用scope
模型中定义的简单RoomsUser
来简化此操作,例如:
# rooms_user.rb
scope :as_admins, -> { where(is_admin: true) }
并在proc中使用它:
# user.rb
has_many :administrated_rooms,
proc { as_admins },
through: :rooms_users,
class_name: 'Room',
source: :rooms
source
选项解释:
使用
source: :users
,我们告诉Rails在RoomsUser模型上使用名为:users
的关联(因为它是:rooms_users
使用的模型)。< / p>
(来自Understanding :source option of has_one/has_many through of Rails)
答案 1 :(得分:0)
您想使用has_many through:
代替has_and_belongs_to_many
。两者都定义了多个到多个关联,但has_many through:
使用模型作为连接行。
缺乏模型会使has_and_belongs_to_many
非常有限。由于间接创建了行,因此无法直接查询连接表或添加其他列。
class User < ApplicationRecord
has_many :user_rooms
has_many :rooms, through: :user_rooms
end
class Room < ApplicationRecord
has_many :user_rooms
has_many :users, through: :user_rooms
end
class UserRoom < ApplicationRecord
belongs_to :user
belongs_to :room
end
您可以使用现有架构,但需要使用migration将表users_rooms
重命名为user_rooms
- 否则rails会将类名称取消为Rooms::User
。< / p>
class RenameUsersRooms < ActiveRecord::Migration[5.0]
def change
rename_table(:users_rooms, :user_rooms)
end
end
但是,我也希望能够打电话 Room.find(1).admins并获取管理员用户列表(其中 rooms_users中的is_admin为true)。我该怎么做?
您想使用左内连接:
User.joins(:user_rooms)
.where(user_rooms: { room_id: 1, is_admin: true })
要将其滚动到类中,您可以设置与应用范围的关联:
class Room < ApplicationRecord
has_many :user_rooms
has_many :users, through: :user_rooms
has_many :user_room_admins, class_name: 'UserRoom', ->{ where(is_admin: true) }
has_many :user_room_admins, through: :user_rooms,
class_name: 'User',
source: :user
end