4

我知道这个问题已经被问了无数次,但我仍然觉得我错过了一些明显的东西。给定一个模型,其中Address包含一个city我们希望使用默认值初始化的字段,比如Awesome City.

到目前为止我已经尝试过:

1)视图中的默认值:

# @file: /app/views/addresses/_form.html.erb
<dt><%= f.label :city %></dt>
<dd><%= f.text_field :city, :value => 'Awesome city' %></dd>

这有效,但感觉不对。用户也无法更改它,该值仍然是Awesome city.

2)覆盖city方法:

# @file: app/models/address.rb
def city
  self[:city] ||= 'Awesome city'
end

该字段呈现为空,因此由于某种原因它不起作用。如果你尝试Address.new.city你会得到默认值。

3)在控制器中分配默认值:

# address doesn't have a controller, we use nested forms
# belongs_to :parent
# @file: /app/controllers/parents_controller.rb
def new
  @parent = Parent.new
  @parent.build_address 
  @parent.address.city = 'Awesome city'
end    

这实际上可行,但我认为它不应该在控制器中,而应该在模型中。

4)添加一个after_initialize调用(是的,它有效,你不必覆盖回调):

# @file: app/models/address.rb
after_initialize :set_default_city
def set_default_city
   self.city = 'Awesome city'
end

这也有效,但是每次实例化对象时都会调用它,这是我们不想要的。

5)JavaScript,这似乎是一个极端的措施,它应该比这更容易。

底线:添加默认值的最佳方法是什么?每次我必须给一个字段一个默认值时,我似乎都在为这样一个简单的事情而努力。还有其他我想念的选择吗?

编辑::我使用 Rails 3.1.4 和 Ruby 1.8.7/1.9.2

4

2 回答 2

4

您可以在迁移文件中定义它:

class CreateAddress < ActiveRecord::Migration
  def change
    create_table :addresses do |t|
      ...
      t.string :city, default: "Awesome City"
      ...

      t.timestamps
    end
  end
end

其他选项是在new动作中定义它,在你的控制器中,这更灵活......所以,当你创建一个新的address时,它将以默认值开始......

 def new
   @address = Address.new
   @address.city ||= "Awesome City"
   ...
 end

编辑- 在模型中定义默认值的可能解决方案:

before_save :set_default_city
def set_default_city
   self.city ||= 'Awesome city'
end
于 2012-06-27T10:32:27.823 回答
2

我的红宝石有点生锈,但有点像

Parent < ActiveRecord::Base
  def self.custom_parent(options)
    custom_parent = self.new
    if options.empty?
      custom_parent.update_attributes(default_options)
    else
      //Iterate over all options and assign them to custom_parent
    end

    return custom_parent
  end
end

你必须创建“default_options”哈希

我认为这不会开箱即用,但我想你明白了我的想法

于 2012-06-27T11:15:59.277 回答