【问题标题】:Adding belongs to relationship to Ruby Gem Mailboxer添加属于关系到 Ruby Gem Mailboxer
【发布时间】:2014-04-07 13:49:03
【问题描述】:

我正在构建一个电子商务应用程序,并希望实现类似消息传递系统的东西。在应用程序中,所有对话都将与Product 模型或Order 模型相关。在这种情况下,我想将相关对象(我想是类型 + id)存储到 Conversation 对象。

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

谢谢。

【问题讨论】:

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


    【解决方案1】:

    我最终定制了 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 %>
    

    【讨论】:

      【解决方案2】:

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

      型号:conversation_link.rb

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

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

      has_many :conversation_link, as: :linkingObject
      

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

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

      【讨论】:

        【解决方案3】:

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

        简单地声明

        acts_as_messagable
        

        在您的订单或产品模型中将完成您正在寻找的内容。

        【讨论】:

        • 嗨@TheIrishGuy,感谢您的回复。但是,acts_as_messageable 只允许 gem 知道哪个对象可以是 gem 的 senderreceiver。应用需要在对话中附加productorder,但发送者和接收者仍然是用户
        • 好吧,你要做的不是用你的自定义逻辑创建一个关注点。比猴子修补会话类以包含该问题。
        【解决方案4】:

        你可以使用类似的东西:

        form_helper :products
        

        并将这些字段添加到消息表单中

        但邮箱自带附件功能(载波)

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

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

        【讨论】:

        • 嗨@Franklin-De-Los-Santos,感谢您的回复。我需要将对话与模型对象联系起来,这样会略有不同。我在想,如果没有比猴子修补 gem 更直接的选项,我宁愿添加另一个与 gem 完全分离的模型......
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多