首页 > 解决方案 > 在 Rails 6 的自动渲染 HTML 中使用自定义名称

问题描述

假设我有这样的模型:

class Item < ApplicationRecord
end

items#newitems#edit, 在app/views/items/_form.html.erb:

<%= f.submit %>

这将根据路由生成一个名为“创建项目”或“更新项目”的提交按钮。

现在我想为生成的按钮文本使用替代名称(并且只在此处!),例如“创建文章”和“更新文章”,同时Item在代码中的其他任何地方保留名称,所以我仍然可以使用items_urlItemsHelper::some_method

使用<%= f.submit "Text" %>不是一种选择,因为它不会保持相同表单在不同视图中呈现之间Create %{model}的差异。Update %{model}

我做了以下尝试但没有成功:

# 1 - no difference observed
class Item < ApplicationRecord
  def display_name
    "Object"
  end
end

# 2 - undefined method `name' for "Artlcle":String
class Item < ApplicationRecord
  def model_name
    "Object"
  end
end

# 3 - undefined method `object_path'
class Item < ApplicationRecord
  def model_name
    ActiveModel::Name.new Item, nil, 'Object'
  end
end

这也不是一个好的解决方案,因为它违反了 Rails 的 DRY 原则。

<% if determine_controller %>
  <%= f.submit "Some text" %>
<% else %>
  <%= f.submit "Some other text" %>
<% end %>

我如何实现这个目标?没有可能rails-i18n吗?

附加问题:您的答案中的解决方案是否也适用于 Rails 5?

标签: ruby-on-railsrubyruby-on-rails-6

解决方案


也许有点太老套了,但是猴子补丁可以完成这项工作(感谢@AbM提供到 Rails 源的链接):

class Item < ApplicationRecord
  def model_name.human
    'Article'
  end
end

为了让生活更轻松,我在基类中编写了一个“辅助方法”:

class ApplicationRecord < ActiveRecord::Base
  def self.display_name(name)
    self.model_name.define_singleton_method :human do
      name
    end
  end
end

然后我可以这样做:

class Item < ApplicationRecord
  display_name 'Article'
end

推荐阅读