2012-05-27 35 views
1

我以轨道上的红宝石开始。我有一个简单的脚手架。Ruby模型 - 初始化时的设置值

这里是我的模型:

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="<%[email protected]("%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 

我只是取代了原来的代码:出生属性,为你可以看到这里:

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

当我选择选项新诞生的属性似乎没有价值,我得到这个execption

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' 

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

在此先感谢。

+1

您可能不想重写初始化,而是使用回调。 –

+0

谢谢,但现在我得到了:未定义的方法'strftime'为零:NilClass。代码:def after_initialize birth = DateTime.now.in_time_zone.midnight end –

+0

'@ pet'是一个新实例化的对象(即你在控制器中调用'@pet = Pet.new')?我认为你在这里的做法可能是错误的。如果您想要出生的“默认”值,可以通过迁移将其设置在数据库中。否则,您可以将其设置在控制器中,或者如果当前不存在任何值,则可以将该字段的值设置为今天的值。 –

回答

1

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

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

我怀疑after_initialize方法不为你工作的主要原因是,你需要明确地使用self作为self.birth =而非birth =。 Ruby认为你正在定义一个名为birth的局部变量,而不是为内部通过method_missing实现的ActiveRecord属性birth赋值。这就是为什么@pet.birthnil,即使它可能看起来是你给它分配了一个值。

另请注意,当您通过从数据库加载它们来实例化它们时,即使对于持久对象,也会调用after_initialize回调。在通过initialize为新记录分配属性之后,它也被调用。因此,为了防止您的默认被践踏(对于坚持和新记录)的用户指定的值,一定要做到这样的事情:在if birth.nil?

0

那么这里是

self.birth = value if birth.nil? 

重点解决方案。首先,没有执行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