仅在视图中覆盖活动记录模型属性

时间:2010-10-04 16:51:55

标签: ruby-on-rails activerecord internationalization model

我有一个名为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'

例如:

拥有'Coder'工作的人'Bob'应该是会计师的'奴隶',并且应该是那些使用法语应用程序的人'编码',但我应该能够为每个编码员找到一个找到。

1 个答案:

答案 0 :(得分:0)

如果您想以不同的方式呈现作业的名称,那么最好的地方就是帮助。这使表示逻辑远离模型。您的帮助程序代码等同于您的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类,如果委托者类没有定义方法,它只会委托对'wrapped'对象的任何方法调用。