Rails - text_field中的默认值,但仅适用于new_record?

时间:2011-01-09 04:27:01

标签: ruby-on-rails erb

在内容模型上有一个名为slug的属性。在创建新记录时,我想使用帮助程序来填充此字段,但在现有记录中,我想使用数据库中的值。

目前我有:

<% if @content.new_record? %>
  <%= f.text_field :slug, :value => "#{generate_slug(6)}" %>
<% else %>
  <%= f.text_field :slug %>
<% end %>

但这看起来有点冗长。这是最好的方式,还是别的办法? (Rails newb只是试图在我不确定的问题上找到“Rails方式”)


修改

我应该注意,帮助程序当前位于/app/helpers/application_helper.rb 已移至内容控制器中的私有操作。大卫的回答很有效。

3 个答案:

答案 0 :(得分:24)

在您的控制器中

@content.slug ||= generate_slug(6)

这将为slug属性分配值(如果不存在)

然后,在您的视图中,您只需使用

即可
<%= f.text_field :slug %>

答案 1 :(得分:0)

选项

  1. 在模型中尝试after_initialize回调。
  2. 尝试在模型中创建一个设置默认值的方法,并在控制器中的新操作中调用它。如果创建失败并且渲染为new,也请调用此方法。请记住,只有在没有值时才使用|| =运算符设置默认值。
  3. 要遵循的示例。我正在打电话!

答案 2 :(得分:0)

我碰巧在我的项目中使用jQuery,所以当我想要这样的功能时,我通常会使用类似labelify的东西。然后,我使用<%= f.text_field :slug, :title => generate_slug(6) %>之类的东西。 (热门提示,你不需要把#generate_slug调用放在一个字符串里面,如果它返回的东西会自动解析成一个字符串,事实上如果你不这样做就会更有效率。 。)

如果您不想使用jQuery方法,您可能希望将这条逻辑包装在模型中。

def Content < ActiveRecord::Base
  def slug
    self.new_record? ? self.slug_for_new_record : attributes[:slug]
  end

  private
  def slug_for_new_record
    # I don't know what you're doing in generate_slug, but it sounds model-
    # related, so if so, put it here and not in a helper
  end
end

如果它真的属于视图,还有一个选择就是让你的Ruby更简洁一些(你必须判断它是否更具可读性):

<%= f.text_field :slug, :value => (generate_slug(6) if @content.new_record?) %>

别忘了(generate_slug(6) if @content.new_record?)周围的parens。如果您这样做,if将应用于text_field,这不是您想要的。

但还有更多方法可以做到这一点。如果您的逻辑可能会发生变化并且您在整个rails项目中粘贴此代码,则上面的代码行并不是很好。当我想添加一个&#39; required&#39;类到我的文本字段,但只有当它们是新记录时(我们有一些我们不想让人们清理的遗留数据),我用required_field方法创建了我自己的表单构建器名为text_field,并添加了“必要的”#39}。如果该项是新记录,则为class。这似乎是一项工作,但我们有大约20种不同的表单,每种表单都有可能包含多个必填字段,而且在一个地方更改业务逻辑要容易得多。因此,如果你真的认为这个逻辑属于视图,但你已经获得了大量这些代码行,并且你不想在一百万个地方改变它,那么FormBuilder就是你要走的路。 。我认为这在大多数情况下比帮手更漂亮,更合适,但同样,美丽在旁观者的眼中。这里的代码有点适合您的情况:

# config/environment.rb
ActionView::Base.default_form_builder = NamespacesAreFun::FormBuilder

# lib/namespaces_are_fun/form_builder.rb
module NamespacesAreFun
  class FormBuilder < ActionView::Helpers::FormBuilder
    def slug_field(method, options = {})
      opts = options.to_options
      opts.merge!(:value => generate_slug) if self.object.new_record?
      text_field(method, opts)
    end
  end
end

# views/.../your_view.html.erb
<%= f.slug_field :slug %>

希望所有这些不同的方法适合您的项目。