Reputation: 53
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
It's a part of model, but it's enouth. When save field (from irb or from sinatra application) :birthday not save in DB. But in irb, i see object, where :birthday exist and it Date format. When change field manual (from irb): f.birthday = Date.new f.save In object and in DB result appear (in obj as Date obj, in DB as "2010-2-3")
Help me please to understand, what wrong with before in model.
Sorry for my not good enlish.
Upvotes: 2
Views: 1338
Reputation: 1813
DataMapper documentation recommends #attribute_set
Sets the value of the attribute and marks the attribute as dirty if it has been changed so that it may be saved. Do not set from instance variables directly, but use this method.
In your case:
before :save do
set_attribute(:birthday => Date.new(self.birthday_year.to_i, self.birthday_month.to_i, self.birthday_day.to_i))
end
For what it's worth, unless I needed to use all the fields in SELECT criteria, I would save either the integer fields or the date, not both:
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))
Or
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
Upvotes: 3
Reputation: 5743
You should use property mutator method. Setting the ivar doesn't trigger dirty tracking. Just do this:
self.birthday = Date.new(birthday_year.to_i, birthday_month.to_i, birthday_day.to_i)
Also it would be better to use Integer as the property type for year, month and day.
Upvotes: 4