Rails:列表Conversation.users,如果多个user_ids存储在多个列
Rails: list Conversation.users, if multiple user_ids stored in multiple columns
如果与 Conversations
关联的所有用户存储在不同的列中,我如何列出所有这些用户。
即,对于下面的示例,我如何调用 c.users
并获得 [#<User id: 1>, #<User id: 2>]
。
Class:
class Conversation < ApplicationRecord
belongs_to :user, foreign_key: :initiator_id
belongs_to :user, foreign_key: :recipient_id
end
正在测试:
>> c = Conversation.first
>> c.initiator_id
=> 1
>> c.recipient_id
=> 2
>> c.user
=> #<User id: 2> # This only lists one user
> c.users
NoMethodError: undefined method `users'
一个解决方案是创建一个子查询
SELECT
conversations.id AS conversation_id,
initiator_id AS user_id
UNION
SELECT
conversations.id AS conversation_id,
recipient_id AS user_id
这将直接为您提供用户和对话之间的关系。如果您经常这样做,您可以将其创建为视图,以便您可以直接在 Activerecord 中查询此 table。
整个查询是
SELECT conversations_users.user_id
FROM
(SELECT
conversations.id AS conversation_id,
initiator_id AS user_id
UNION
SELECT
conversations.id AS conversation_id,
recipient_id AS user_id) conversations_users
WHERE conversations_users.conversation_id IN ?
在哪里使用具有适当值的 conversation_id。
如果您经常这样做,那么 运行 迁移以将其创建为视图是有意义的。
高清
ActiveRecord::Base.connection.execute <<-SQL
CREATE OR REPLACE VIEW conversations_users_view AS
SELECT
conversations.id AS conversation_id,
initiator_id AS user_id
UNION
SELECT
conversations.id AS conversation_id,
recipient_id AS user_id
SQL
end
然后你创建一个conversations_users活动记录模型
class ConversationsUser < ActiveRecord::Base
self.table_name = 'conversations_users_view'
end
那你就可以直接查询了
users = ConversationsUser.where('conversations_id IN ?', c.id)
创建两个关联并像这样使用它们:
class Conversation < ApplicationRecord
belongs_to :initiator, foreign_key: :initiator_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
def users
[initiator, recipient]
end
end
不确定这是否是一个好方法,但你可以实现你想要的
如果与 Conversations
关联的所有用户存储在不同的列中,我如何列出所有这些用户。
即,对于下面的示例,我如何调用 c.users
并获得 [#<User id: 1>, #<User id: 2>]
。
Class:
class Conversation < ApplicationRecord
belongs_to :user, foreign_key: :initiator_id
belongs_to :user, foreign_key: :recipient_id
end
正在测试:
>> c = Conversation.first
>> c.initiator_id
=> 1
>> c.recipient_id
=> 2
>> c.user
=> #<User id: 2> # This only lists one user
> c.users
NoMethodError: undefined method `users'
一个解决方案是创建一个子查询
SELECT
conversations.id AS conversation_id,
initiator_id AS user_id
UNION
SELECT
conversations.id AS conversation_id,
recipient_id AS user_id
这将直接为您提供用户和对话之间的关系。如果您经常这样做,您可以将其创建为视图,以便您可以直接在 Activerecord 中查询此 table。
整个查询是
SELECT conversations_users.user_id
FROM
(SELECT
conversations.id AS conversation_id,
initiator_id AS user_id
UNION
SELECT
conversations.id AS conversation_id,
recipient_id AS user_id) conversations_users
WHERE conversations_users.conversation_id IN ?
在哪里使用具有适当值的 conversation_id。 如果您经常这样做,那么 运行 迁移以将其创建为视图是有意义的。 高清
ActiveRecord::Base.connection.execute <<-SQL
CREATE OR REPLACE VIEW conversations_users_view AS
SELECT
conversations.id AS conversation_id,
initiator_id AS user_id
UNION
SELECT
conversations.id AS conversation_id,
recipient_id AS user_id
SQL
end
然后你创建一个conversations_users活动记录模型
class ConversationsUser < ActiveRecord::Base
self.table_name = 'conversations_users_view'
end
那你就可以直接查询了
users = ConversationsUser.where('conversations_id IN ?', c.id)
创建两个关联并像这样使用它们:
class Conversation < ApplicationRecord
belongs_to :initiator, foreign_key: :initiator_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
def users
[initiator, recipient]
end
end
不确定这是否是一个好方法,但你可以实现你想要的