Adding belongs to relationship to Ruby Gem Mailboxer

前端 未结 4 1960
情话喂你
情话喂你 2021-01-03 10:08

I am building an e-com application and would like to implement something like a messaging system. In the application, all conversation will be related to either a Prod

4条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-03 10:12

    I ended up customizing the Mailboxer gem to allow for a conversationable object to be attached to a conversation.

    In models/mailboxer/conversation.rb

    belongs_to :conversationable, polymorphic: true
    

    Add the migration to make polymorphic associations work:

    add_column :mailboxer_conversations, :conversationable_id, :integer
    add_column :mailboxer_conversations, :conversationable_type, :string
    

    In lib/mailboxer/models/messageable.rb you add the conversationable_object to the parameters for send_message:

    def send_message(recipients, msg_body, subject, sanitize_text=true, attachment=nil, message_timestamp = Time.now, conversationable_object=nil)
      convo = Mailboxer::ConversationBuilder.new({
        :subject    => subject,
        :conversationable => conversationable_object,
        :created_at => message_timestamp,
        :updated_at => message_timestamp
      }).build
    
      message = Mailboxer::MessageBuilder.new({
        :sender       => self,
        :conversation => convo,
        :recipients   => recipients,
        :body         => msg_body,
        :subject      => subject,
        :attachment   => attachment,
        :created_at   => message_timestamp,
        :updated_at   => message_timestamp
      }).build
    
      message.deliver false, sanitize_text
    end   
    

    Then you can have conversations around objects:

    class Pizza < ActiveRecord::Base
      has_many :conversations, as: :conversationable, class_name: "::Mailboxer::Conversation"    
      ...
    end
    
    class Photo < ActiveRecord::Base
      has_many :conversations, as: :conversationable, class_name: "::Mailboxer::Conversation"    
      ...
    end
    

    Assuming you have some users set up to message each other

    bob = User.find(1)
    joe = User.find(2)
    pizza = Pizza.create(:name => "Bacon and Garlic")
    
    bob.send_message(joe, "My Favorite", "Let's eat this", true, nil, Time.now, pizza)
    

    Now inside your Message View you can refer to the object:

    Pizza Name: <%= @message.conversation.conversationable.name %>
    

提交回复
热议问题