2011-03-29 49 views
2
class Order 
    include Datamapper::Resource 

    property :birthday_day, String 
    property :birthday_month, String 
    property :birthday_year, String 
    property :birthday, Date 

    before :save do 
    @birthday = Date.new(@birthday_year.to_i, @birthday_month.to_i, @birthday_day.to_i) 
    end 
end 

这是模型的一部分,但它是enouth。 当保存字段(来自irb或来自sinatra应用程序):生日不保存在数据库中。但是在irb中,我看到了对象,其中:生日存在,它是日期格式。 当改变字段手册(由IRB): f.birthday = Date.new f.save 在对象和在DB结果出现(在物镜作为物镜日期,在DB为 “2010-2-3”)红宝石DataMapper不保存属性设置在钩子

请帮我理解,模型中之前有什么不妥。

对不起,我不好。

回答

4

您应该使用属性增变器方法。设置伊娃不会触发脏跟踪。只要这样做:

self.birthday = Date.new(birthday_year.to_i, birthday_month.to_i, birthday_day.to_i) 

此外,最好使用整数作为年,月和日的属性类型。

+0

非常感谢您! – AntonKrutikov 2011-03-29 13:51:13

+0

您是否接受答案或投票+1如果它已经解决了您的问题? – Kokizzu 2013-08-14 08:12:01

3

DataMapper的文档建议#attribute_set

设置属性的值,如果它已被更改,以便它可以保存标记属性为脏。不要直接从实例变量设置,而是使用此方法。

你的情况:

before :save do 
    set_attribute(:birthday => Date.new(self.birthday_year.to_i, self.birthday_month.to_i, self.birthday_day.to_i)) 
end 

对于它的价值,除非我需要使用SELECT条件的所有领域,我会救不整场或日期,而不是两个:

class Order 
    include Datamapper::Resource 

    property :birthday, Date 
end 

# change month 
o = Order.create(:birthday => Date.new(...)) 
o.update(:birthday => Date.new(o.birthday.year, new_month, o.birthday.mday)) 

或者

class Order 
    include Datamapper::Resource 

    property :birthday_day, String 
    property :birthday_month, String 
    property :birthday_year, String 

    def birthday 
    if self.birthday_day && self.birthday_month && self.birthday_year 
     Date.new(self.birthday_day, ...) 
    end 
    end 
end 
+0

self.birthday =(v)和attribute_set(:birthday,v)做同样的事情,除了之前的返回资源的状态对象,后者是设置的值。 – solnic 2011-03-29 16:19:36

+0

好点@ solnic。我通常更喜欢_set,_get方法,因为除了文档的声明之外,我发现它更容易阅读,因为我知道如果看到'_set(:foo ...)',但没有其他事情发生,但'self.foo = x'有时会被其他可能或不可取的行为覆盖。)然后再次,_set不是简洁的。 – 2011-03-30 14:43:19