Ruby on rails 是否有一种方法可以跨控制器使用?如果有,如何使用?

Ruby on rails 是否有一种方法可以跨控制器使用?如果有,如何使用?,ruby-on-rails,controller,Ruby On Rails,Controller,我有几个控制器,每个控制器都有一个不同类的实例(电子邮件、电话、信件等),它们都必须经过相同的替换: @email.message.gsub!("{FirstName}", @contact.first_name) @email.message.gsub!("{Company}", @contact.company_name) @email.message.gsub!("{Colleagues}", @colleagues.to_sentence) @email.message.gsub!("

我有几个控制器,每个控制器都有一个不同类的实例(电子邮件、电话、信件等),它们都必须经过相同的替换:

@email.message.gsub!("{FirstName}", @contact.first_name)
@email.message.gsub!("{Company}", @contact.company_name) 
@email.message.gsub!("{Colleagues}", @colleagues.to_sentence)
@email.message.gsub!("{NextWeek}", (Date.today + 7.days).strftime("%A, %B %d"))
@email.message.gsub!("{ContactTitle}", @contact.title )
例如,@call.message for call,@letter.message for letter,等等

这不是很干。我尝试了以下方法:

class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time

  def message_sub(asset, contact, colleagues)
    asset.message.gsub!("{FirstName}", contact.first_name)
    asset.message.gsub!("{Company}", contact.company_name) 
    asset.message.gsub!("{Colleagues}", colleagues.to_sentence)
    asset.message.gsub!("{NextWeek}", (Date.today + 7.days).strftime("%A, %B %d"))
    asset.message.gsub!("{ContactTitle}", contact.title )
  end
end

但上述方法不起作用。

我认为我们缺少解决此问题所需的信息。请参阅本指南第3节:

逐步检查代码,并在每个点检查变量,看看它们是否符合预期

有时间时,一定要阅读整个指南。它为Rails编程提供了一套非常宝贵的工具


作为旁注,您提供的代码感觉更适合在模型中而不是控制器中。您的模型可能是一个很好的候选模型,或者您的模型非常相似,您可以将它们浓缩为一个更通用的模型,以涵盖您需要的内容。如果这两个选项中的任何一个都很合适,您可以将
消息\u sub
移出控制器并移动到模型中。

问题可能在于gsub!处理ActiveRecord返回的字符串对象的实例。要将属性更改通知ActiveRecord,应调用方法
message=(value)
。因此,您的方法如下:

def message_sub(asset, contact, colleagues)
  asset.message = asset.message.
      gsub("{FirstName}", contact.first_name).
      gsub("{Company}", contact.company_name).
      gsub("{Colleagues}", colleagues.to_sentence).
      gsub("{NextWeek}", (Date.today + 7.days).strftime("%A, %B %d")).
      gsub("{ContactTitle}", contact.title )
end

(我获得了一些艺术许可来链接gsub方法,但这完全取决于你的喜好)

不清楚问题是在整个控制器中重用方法(如标题所示)还是使用消息模板的最佳方式。 为了在整个控制器中重用该方法,我想您已经通过使用公共类回答了这个问题。然而,正如Awgy所建议的,该位在模型中可能比在控制器中更好

要模板化消息,您可以使用ERB而不是gsub或只是“eval”字符串 (如果您在邮件中使用{}而不是{})


(您甚至可以直接将联系人作为“绑定”传递给eval函数。

就我个人而言,我不会将其委托给控制器,这不就是它的用途吗?

要直接回答您的问题,您需要一个模块。您可以将其放在lib目录中

module MessageSubstitution

  def message_sub(asset, contact, colleagues)
    asset.message.gsub!("{FirstName}", contact.first_name)
    asset.message.gsub!("{Company}", contact.company_name) 
    asset.message.gsub!("{Colleagues}", colleagues.to_sentence)
    asset.message.gsub!("{NextWeek}", (Date.today + 7.days).strftime("%A, %B %d"))
    asset.message.gsub!("{ContactTitle}", contact.title )
  end

end
然后在你的控制器里

class MyController < ApplicationController

  include MessageSubstitution


  def action

    ...

    message_sub(@letter, @contact, @colleagues)

  end

end
然后将其包含在模型级别,然后调用控制器,如
@letter.substituded_message(@contact,@collaborates)


但是,我有点困惑,您发布的内容不起作用。如果它是在ApplicationController上定义的,它应该会起作用。在我看来,基于模块的解决方案更好。

谢谢,我想我是在寻找关于如何做的指导……在传递类或资产名称方面in@Angela:我将答案改为链接到一个有助于y的指南我做了一个调试,但我想我仍在试图弄清楚是否将其作为一个视图方法(如果是,如何)…我不确定它是否准备好用于STI…@Angela:如果要在视图中调用它,只需将其设置为帮助器方法。因此,当您使用调试器时,您是否能够单步调用message_sub并在@letter上查看GSUB?在调用该方法后,@letter是否按预期进行了修改?并将其设置为帮助器方法(在视图中可用)通过在ApplicationController中使用
helper\u方法:message\u sub
(其中定义了message\u sub方法)。不工作意味着?有错误消息吗?另外,我注意到您在第一个代码段调用message方法,但在第二个代码段调用body方法。如果您选中@letter.message,它是否不工作?call、letter等是否都是单独的模型?如果是,您可以发布其中一个模型的示例。应该
@contact\u letter.body=@letter.body
be
@contact\u letter.message=@letter.message
?我有另一行指定它@contact\u letter.body=@letter.body,请参见上文……是的,我想我之前有过这个方法,并放弃了剪切和粘贴,但我也很感谢您改进gsub,我一直在寻找更好的方法来编写代码。让我试试这个out。如果您尝试Angela在控制台中使用的gsub!方法,它确实会正确修改消息并返回记录的修改版本。您无法将更改保存到@letter,但如果我理解她试图做的事情,修改后的消息复制到@contact_letter后,这些更改将被抛出,因此信函的模板可以重用。混合使用消息替换逻辑是一个很好的方法。Jamis Buck在这里写了一篇文章,其中有更多细节:我明白了,所以这作为一个模型级别的模块更好…因为这样无论调用该模型的视图或控制器是什么,我都可以按照描述使用这个方法,对吗?所以对于我来说,在不同的模型中使用它--我需要为信件、电子邮件、电话和明信片ODEL应用此替换项…因此我只想在任何模型上应用一个模块…message.gsub中的“message”是否意味着我的所有模型都必须具有包含被替换文本的属性message?嗯…获取一个错误:未定义的方法“Substituded_message”为了#
module MessageSubstitution

  def message_sub(asset, contact, colleagues)
    asset.message.gsub!("{FirstName}", contact.first_name)
    asset.message.gsub!("{Company}", contact.company_name) 
    asset.message.gsub!("{Colleagues}", colleagues.to_sentence)
    asset.message.gsub!("{NextWeek}", (Date.today + 7.days).strftime("%A, %B %d"))
    asset.message.gsub!("{ContactTitle}", contact.title )
  end

end
class MyController < ApplicationController

  include MessageSubstitution


  def action

    ...

    message_sub(@letter, @contact, @colleagues)

  end

end
module MessageSubstitution

  def substituted_message(contact, colleagues)
    message.gsub("{FirstName}", contact.first_name).
           gsub("{Company}", contact.company_name).
           gsub("{Colleagues}", colleagues.to_sentence).
           gsub("{NextWeek}", (Date.today + 7.days).strftime("%A, %B %d")).
           gsub("{ContactTitle}", contact.title )
  end

end