【问题标题】:Overriding active record model attributes only in the view仅在视图中覆盖活动记录模型属性
【发布时间】:2010-10-04 16:51:54
【问题描述】:

我有一个名为 human 的对象,该对象有一个名为 job 的字段。我希望用户能够添加他们自己的工作(显然会以他们自己的语言添加),但我希望在有人做 Human.job 时翻译数据库中默认的任何工作,rails 可以翻译吗如果它在视图中则为默认值,但如果它在模型中则不是,因为我有一些 sql 逻辑来测试有多少人拥有编码器的工作。

#Human
class Human < ActiveRecord::Base
  validates_presence_of :job, :name
  def job
    if is_view?
     key = job.gsub(/ /,'_')
      translation = I18n.translate("jobs.#{key.downcase}")
      if translation.include?('translation missing:')
        job
      else
        translation
      end
    else
      job
    end
  end
end

#en.yml
en:
  jobs:
    coder: 'coder'

#en-Accountants.yml
en-Accountants:
  jobs:
    coder: 'slave'

#fr.yml
fr:
  jobs:
    coder: 'le coder'

例如:

从事“编码员”工作的人类“鲍勃”应该是会计师的“奴隶”,应该是使用法语应用程序的人的“奴隶”,但我应该仍然能够为每个编码员进行查找。

【问题讨论】:

    标签: ruby-on-rails activerecord internationalization model


    【解决方案1】:

    如果您想以不同的方式呈现工作名称,那么最好的地方就是在助手中。这使表示逻辑远离您的模型。您的帮助代码将等同于您的 is_view? 代码。

    诚然,这意味着您必须在每次显示作业名称时调用它,这可能是您试图避免的。您可以创建一个委托类,在您的视图中用于人类。您仍然需要记住创建人类的委托版本,尽管当您将它们传递给您的视图时。

    例如这样的:

    class HumanView < SimpleDelegator
      def job
        unchanged_job = super # The actual saved job string
        key = unchanged.gsub(/ /,'_')
        translation = I18n.translate("jobs.#{key.downcase}")
        if translation.include?('translation missing:')
          unchanged_job
        else
          translation
        end
      end
    end
    

    然后在你的控制器中你可以这样做:

    def index
      humans = Human.find(:all) # For example
      @humans = humans.map { |h| HumanView.new(h) }
    end
    
    def show
      h = Human.find(params[:id])
      @human = HumanView.new(h)
    end
    

    SimpleDelegator 是一个标准的 ruby​​ 类,如果委托者类没有定义方法,它只会将任何方法调用委托给“包装”对象。

    【讨论】:

    • 感谢沙德威尔!这是一个很大的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多