添加属于Ruby Gem Mailboxer的关系

时间:2014-04-07 13:49:04

标签: ruby-on-rails ruby-on-rails-4 mailboxer

我正在构建一个e-com应用程序,并希望实现类似于消息传递系统的功能。在该应用程序中,所有对话都与Product模型或Order模型相关。在这种情况下,我想将相关对象(类型+ id,我猜)存储到Conversation对象。

要添加字段,当然我可以生成并运行迁移,但是,由于模型和控制器包含在gem中,我如何声明关系? (belongs_to :linking_object, :polymorphic)和控制器?有什么想法吗?

谢谢。

4 个答案:

答案 0 :(得分:4)

我最终自定义了Mailboxer gem,允许将conversationable对象附加到对话中。

models/mailboxer/conversation.rb

belongs_to :conversationable, polymorphic: true

添加迁移以使多态关联起作用:

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

lib/mailboxer/models/messageable.rb中,您将conversationable_object添加到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   

然后你可以围绕对象进行对话:

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

假设您已将某些用户设置为互相发送消息

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)

现在在您的消息视图中,您可以引用该对象:

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

答案 1 :(得分:1)

虽然重写自定义对话系统将是提供自定义要求的最佳长期解决方案(例如与其他模型链接),但为了节省一些时间,我已实现与ConversationLink的链接模型。我希望这对将来担任我职位的人都有用。

型号:conversation_link.rb

class ConversationLink < ActiveRecord::Base
  belongs_to :conversation
  belongs_to :linkingObject, polymorphic: true
end

然后在每个模型中,我的目标是与conversation链接,我只需添加:

has_many :conversation_link, as: :linkingObject

这只允许您从链接对象获取相关对话,但反向链接的编码可以通过模块中定义的函数完成。

这不是一个完美的解决方案,但至少我不需要修补宝石......

答案 2 :(得分:0)

gem会自动为您解决这个问题,因为他们已经构建了一个解决方案,您自己的域逻辑中的任何模型都可以充当混乱对象。

简单地声明

acts_as_messagable

在您的订单或产品模型中,您将完成所需的工作。

答案 3 :(得分:0)

你可以使用类似的东西:

form_helper :products

并将这些字段添加到邮件表单

但邮箱附带附件功能(carrierwave)

如果您在邮件中需要附件等内容,这可能会有所帮助:

https://stackoverflow.com/a/12199364/1230075