Ruby Model - 初始化时设置值

时间:2012-05-27 02:40:08

标签: ruby-on-rails ruby-on-rails-3

我从铁轨上的红宝石开始。我有一个简单的脚手架。

这是我的模特:

class Pet < ActiveRecord::Base
  belongs_to :user
  belongs_to :petRace
  attr_accessible :birth, :exactAge, :nick
  def initialize
    birth = DateTime.now.in_time_zone.midnight
  end
end

html代码

<%= form_for @pet, :html => { :class => 'form-horizontal' } do |f| %>
  <div class="control-group">
    <%= f.label :nick, :class => 'control-label' %>
    <div class="controls">
      <%= f.text_field :nick, :class => 'text_field' %>
    </div>
  </div>
  <div class="control-group">
    <%= f.label :birth, :class => 'control-label' %>
    <div class="controls">
    <div class="input-append date datepicker" data-date="<%=@pet.birth.strftime("%d/%m/%Y") %>" data-date-format="dd/mm/yyyy">
        <%= f.text_field :birth, :class => 'input-append', :value => @pet.birth.strftime("%d/%m/%Y") %>
    <span class="add-on"><i class="icon-th"></i></span>
    </div>
  </div>

  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
                pets_path, :class => 'btn' %>
  </div>
<% end %>

控制器:

 def new
    @pet = Pet.new   
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @pet }
    end
  end

我只需替换:birth属性的原始代码,如下所示:

<%= f.text_field :birth, :class => 'input-append', :value => @pet.birth.strftime("%d/%m/%Y") %>

当我选择新选项时,出生属性似乎没有价值,我得到了这个执行

undefined method `[]' for nil:NilClass


Extracted source (around line #11):

8:      
9:  </script>
10: <%end%>
11: <%= form_for @pet, :html => { :class => 'form-horizontal' } do |f| %>
12:   <div class="control-group">
13:     <%= f.label :nick, :class => 'control-label' %>
14:     <div class="controls">

 app/views/pets/_form.html.erb:11:in `_app_views_pets__form_html_erb__3291519358612565784_70159905628180'
app/views/pets/new.html.erb:4:in `_app_views_pets_new_html_erb__1494749415896629355_70159907398120'
app/controllers/pets_controller.rb:28:in `new'

我的理解是,出生值是根据实际日期和时间设置的(在初始化方法中)。我错了还是错过了什么?当我编辑记录时我没有问题。

提前致谢。

2 个答案:

答案 0 :(得分:1)

有多种方法可以将默认值设置为@Rob在评论中提到。

@Dave在评论中提到的回调也是个好主意。

我怀疑after_initialize方法不适合您的主要原因是您需要明确使用self,而不是self.birth =而不是birth =。 Ruby认为您正在定义名为birth的局部变量,而不是将值分配给ActiveRecord的属性birth,该值在内部通过method_missing实现。这就是@pet.birthnil的原因,即使您可能看起来为其指定了值。

另请注意,当您通过从数据库加载实例化持久对象时,即使对于持久对象,也会调用after_initialize回调。在通过initialize为新记录分配属性后,也会调用它。因此,为了防止默认情况下用户指定的值被踩踏(对于持久记录和新记录),请务必执行以下操作:

self.birth = value if birth.nil?

强调if birth.nil?

答案 1 :(得分:0)

这是解决方案。首先,没有执行after_initialize方法。但经过这次修改后,它起了作用:

class Pet < ActiveRecord::Base
  belongs_to :user
  belongs_to :petRace
  attr_accessible :birth, :exactAge, :nick
  after_initialize :init
  protected
    def init
      self.birth = DateTime.now.in_time_zone.midnight
    end
end