Sunny, I had a similar requirement in which a date could be only
partially known -- could be a full date (Oct 11, 1998), just a month
(Oct 1998), or just a year (1998). I ended up creating a new class
PartialDate which wrapped two attributes, the date, and the "mask",
letting the mask represent the amount of specificity of the date (0
for the date represents a full date, 1 for only month and year, 2 for
only year). Saving the date and making it work with ActiveRecord was a
real challenge -- I ended up patching
execute_callstack_for_multiparameter_attributes to break the date
field into its two parts, say, "born_date" and "born_mask".
The born_date would always be a valid date (defaulting to the first of
the month if mask was 1 and the first of the year if mask is 2).
<code>
class ActiveRecord::Base
class << self
def mask_attributes (*cols)
self.send("attr", *cols)
write_inheritable_array("attr_masked", cols + (masked_attributes
|| []))
cols.each do |col|
attr_protected((col.to_s + "_mask").to_sym)
attr_protected((col.to_s + "_date").to_sym)
class_eval <<-"EOL"
def #{col.to_s}
@#{col.to_s} ||= if #{col.to_s}_date
PartialDate.new #{col.to_s}_date,
#{col.to_s}_mask
else
nil
end
end
def #{col.to_s}=(dt)
if dt.nil?
self.#{col.to_s}_date = nil
self.#{col.to_s}_mask = nil
else
case dt
when String
@#{col.to_s} = PartialDate.new(dt)
self.#{col.to_s}_date = @#{col.to_s}.date
self.#{col.to_s}_mask = @#{col.to_s}.mask
when PartialDate
@#{col.to_s} = dt
self.#{col.to_s}_date = dt.date
self.#{col.to_s}_mask = dt.mask
when Date, DateTime
@#{col.to_s} = PartialDate.new(dt,0)
self.#{col.to_s}_date = @#{col.to_s}.date
self.#{col.to_s}_mask = @#{col.to_s}.mask
end #case
end #if else
end #def
EOL
end
end
def masked_attributes
read_inheritable_attribute("attr_masked") ||
write_inheritable_array("attr_masked", [])
end
def is_mask_column?(col_name)
col = col_name.to_s
if col =~ /^(.*)(_date|_mask)$/
base_col = $1
return is_masked?(base_col)
end
false
end
def is_masked?(col_name)
masked_attributes.include?(col_name.to_sym)
end
private
def
execute_callstack_for_multiparameter_attributes_with_mask(callstack)
new_callstack = Hash.new()
callstack.each_with_index do |arr, i|
name, values = *arr
if self.class.is_masked? name
date_name = name + "_date"
set_mask(name, values.nil? ? 0 : 3 - values.length)
new_callstack.merge!({date_name => values})
else
new_callstack.merge!({name => values})
end
end
execute_callstack_for_multiparameter_attributes_without_mask(new_callstack)
end
def set_mask(col,value)
self.send("#{col}_mask=",value)
end
</code>
So I could use it like so:
class Person < ActiveRecord::Base
mask_attributes :born, :died
end
and the database would look like
table people
born_date date
born_mask integer
died_date date
died_mask integer
The code for PartialDate is an unreadable mess because of all the
regexes I use, but it shouldn''t be too hard to cobble something
together for your own use.
Hope that helps
On Apr 28, 2:09 am, Sunny Bogawat <ruby-forum-incom...@andreas-s.net>
wrote:> hello,
> i am developing one application i want to set work date in which
> (day,month,year)any be blank. so how i do it? what i do in controller
> model rhtml.
> how i achieved it? i saw select date syntax but i haven''t
understand it?
> --
> Posted viahttp://www.ruby-forum.com.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Core" group.
To post to this group, send email to rubyonrails-core@googlegroups.com
To unsubscribe from this group, send email to
rubyonrails-core-unsubscribe@googlegroups.com
For more options, visit this group at
groups.google.com/group/rubyonrails-core?hl=en
-~----------~----~----~----~------~----~------~--~---