【问题标题】:Rails - Mailboxer gem : adding relationships to ConversationRails - Mailboxer gem:向对话添加关系
【发布时间】:2013-07-22 08:57:06
【问题描述】:
我们目前在我们的项目中使用Mailboxer,它运行良好。
现在我们要将Requests 添加到Conversations。基本上,这个想法是添加一个
has_one :request, :foreign_key => 'request_id'
但我们无法访问 conversation.rb,因为它属于 gem。
我们已经阅读了有关自定义 gem(here 和 here)的信息,但提供的解决方案似乎不太好。
实现我们想要的最佳方式是什么?
我们可以:
- 将 gem 模型扩展到我们可以编辑的自定义模型?
- 有一种“干净”的方式来编辑 conversation.rb 吗?
谢谢
【问题讨论】:
标签:
ruby-on-rails-3
gem
relationship
mailboxer
【解决方案1】:
这个问题已经有一年多了,但我想我会分享我在 Rails 4 环境中遇到的类似问题的解决方案。
基本上:
- 创建一个继承自
Mailboxer::Conversation 模型的新子模型
- 将关联添加到新的子模型。
- 创建关联时使用
becomes 方法
为了说明,这是我的新模型文件,名为 AppConversation,继承自 Mailboxer::Conversation 类:
class AppConversation < Mailboxer::Conversation
has_one :request, inverse_of: :app_conversation
end
Request模型类中的对应关联:
class Request < ActiveRecord::Base
belongs_to :app_conversation, inverse_of: :request
end
然后,在我需要访问关联的代码中,我首先通过mailboxer gem 提供的API 获取mailboxer 的对话对象,然后使用ActiveRecord becomes 方法创建/修改/读取关联。例如:
def some_controller_action
# get a mailboxer conversation
@conversation = current_user.mailbox.conversations.find(params[:id])
# get the request object associated to the conversation
@request = @conversation.becomes(AppConversation).request
# create a new request association
new_request = Request.new
@conversation.becomes(AppConversation).request = new_request
end
【解决方案2】:
我真的很喜欢@richsinn 的方法(非常干净,但你必须记得打电话给becomes)。另一种解决方案是使用一些元编程将一些方法直接添加到Mailboxer::Conversationclass。例如。可以将以下代码添加到 config/initializers/mailboxer.rb:
Mailboxer.setup do |config|
[...]
end
Mailboxer::Conversation.class_eval do
belongs_to :request
end
理想情况下,我们可以将此代码放在 app/models/conversation.rb 之类的文件中,但当我们调用 Mailboxer::Conversation 时,Rails 不会自动加载此文件。