【发布时间】:2015-12-06 04:30:14
【问题描述】:
用户拥有并属于许多对话。一个对话拥有并属于许多用户,并且有许多消息。一条消息属于一个用户,属于一个会话。
一个非常简单的关系模型,最初运行良好,但现在让我很头疼,因为我将它重构为适用于群组消息,即两个以上用户之间的消息。
我以前只对 HABTM 关联进行过浅薄的工作,无法弄清楚如何检查给定用户数组之间是否已经存在对话。此检查将在对话控制器中进行,可能通过模型中定义的范围进行。编辑:此检查可能只会发生在两个用户之间的对话中。例如,
A conversation between User 1 and User 2 already exists.
User 1 sends a message to User 2 via the "Compose New Message" page.
The preexisting conversation is found and selected, and the new message is inserted into it.
对
A conversation between User 1, User 2, and User 3 already exists.
User 1 sends a message to User 2 and User 3 via the "Compose New Message" page.
A new conversation is made, rather than searching for a pre-existing conversation.
models/conversation.rb
class Conversation < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :messages, dependent: :destroy
scope :between, -> users do
uhhhhhhhhh???
something like
users.each do |u|
then a where("conversations.user.id = ?").yadayadayada query
end
end
end
控制器/conversations_controller.rb
[snip]
def create
if Conversation.between(params[:users]).present?
@conversation = Conversation.between(params[:users]).first
else
@conversation = Conversation.create!(conversation_params)
end
redirect_to conversation_messages_path(@conversation)
end
models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :conversations
[snip lots of other stuff]
end
models/message.rb
class Message < ActiveRecord::Base
belongs_to :conversation
belongs_to :user
validates_presence_of :body, :conversation_id, :user_id
end
db/migrate/create_messages.rb
class CreateMessages < ActiveRecord::Migration
def up
create_table :messages do |t|
t.text :body
t.references :conversation, index: true
t.references :user, index: true
t.boolean :read, :default => false
t.timestamps
end
end
def down
drop_table :messages
end
end
db/migrate/create_conversations.rb
class CreateConversations < ActiveRecord::Migration
def change
create_table :conversations do |t|
t.string :subject
t.timestamps
end
end
def down
drop_table :conversations
end
end
db/migrate/create_conversations_users_join
class CreateConversationsUsersJoin < ActiveRecord::Migration
def change
create_table :conversations_users, id: false do |t|
t.belongs_to :conversation, index: true
t.belongs_to :user, index: true
end
end
end
更新:尝试了@DavidStosik 的解决方案,但在作用域的方法上得到了以下 NameError:
Started POST "/conversations" for 127.0.0.1 at 2015-09-10 16:53:51 -0400
Processing by ConversationsController#create as */*
Parameters: {"user_ids"=>"1 2"}
[1m[35mUser Load (1.0ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Completed 500 Internal Server Error in 3ms
NameError (undefined local variable or method `scoped' for #<Class:0x5afc2b8>):
app/models/conversation.rb:25:in `block in <class:Conversation>'
app/controllers/conversations_controller.rb:13:in `create'
app/controllers/application_controller.rb:19:in `user_time_zone'
【问题讨论】:
-
您希望只在用户之间进行对话,还是对话还包括其他人?
-
仅在特定用户之间。
标签: ruby-on-rails ruby ruby-on-rails-3 has-and-belongs-to-many