A user has and belongs to many conversations. A conversation has and belongs to many users and has many messages. A message belongs to a user and belongs to a conversation.
A very simple relationship model, initially working perfectly, but now giving me a headache as I refactor it to work for group messages, i.e. messages between more than two users.
I've only worked shallowly with HABTM associations before and can't figure out how to check if a conversation already exists between a given array of users. This check will happen in the conversations_controller, probably via a scope defined in the model.
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
controllers/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
Aucun commentaire:
Enregistrer un commentaire