Forum: Rails-core (closed, excessive spam) select date

3548d30217e9921c410db19ce8ce38d0?d=identicon&s=25 Sunny Bogawat (sunny_bogawat)
on 2008-04-28 09:09
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?
82e01981fb1270c0a54c544f9af342c5?d=identicon&s=25 johnjdevine@gmail.com (Guest)
on 2008-04-30 00:57
(Received via mailing list)
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>
82e01981fb1270c0a54c544f9af342c5?d=identicon&s=25 johnjdevine@gmail.com (Guest)
on 2008-04-30 01:00
(Received via mailing list)
Sorry, posted to wrong group -- thought I was in Rails-Talk...
This topic is locked and can not be replied to.