Rails Gem不设置setter方法

时间:2014-03-14 23:20:52

标签: ruby-on-rails ruby activerecord gem

我试图根据Railscast第033集插件制作一个Ruby Gem。我创建了gem并将其作为stringify-time上传到Rubygems.org,但是setter方法无效。

The GitHub Repo

宝石的主要部分

module StringifyTime
  def stringify_time(*names)
    names.each do |name|
      define_method "#{name}_string" do
        read_attribute(name).to_s(:db) unless read_attribute(name).nil?
      end

      define_method "#{name}_string=" do |time_str|
        begin
          write_attribute("#{name}", Time.zone.parse(time_str))
        rescue ArgumentError
          instance_variable_set("@#{name}_invalid", true)
        end
      end

      define_method "#{name}_invalid?" do
        instance_variable_get("@#{name}_invalid")
      end
    end
  end
end

ActiveRecord::Base.send(:extend, StringifyTime)

传入属性符号,并创建getter和setter方法。 getter方法有效,但是当我尝试通过表单更新属性时,数据不会被保存。

使用任务模型中的stringify_time方法

class Task < ActiveRecord::Base                                            
  validates_presence_of :name                                              
  stringify_time :due_at                                                   

  # def due_at_string                                                      
  #   due_at.to_s(:db)                                                     
  # end                                                                    

  # def due_at_string=(due_at_str)                                         
  #   self.due_at = Time.parse(due_at_str)                                 
  # rescue ArgumentError                                                   
  #   @due_at_invalid = true                                               
  # end                                                                    

  def validate                                                             
    errors.add :due_at, 'is invalid' if due_at_invalid? # @due_at_invalid  
  end                                                                      
end

当我取消注释我手动编写的setter方法时,我可以编辑属性。

1 个答案:

答案 0 :(得分:0)

在我尝试在rails控制台中使用生成的方法之后,如评论中建议的@ matjis-van-zuijlen,我能够更新due_at属性。问题是我没有在控制器中将:due_at_string列入白名单。

def task_params                                                                                                                                       
  params.require(:task).permit(:name, :due_at, :due_at_string)                                                                                        
end