Reputation: 5560
I have a model with a handful of related date fields.
def started_at_date=(value)
@started_at_date = value
end
def completed_at_date=(value)
@completed_at_date = value
end
...
The getters are handled via method_missing
and that works great.
def method_missing(method, *args, &block)
if method =~ /^local_(.+)$/
local_time_for_event($1)
elsif method =~ /^((.+)_at)_date$/
self.send :date, $1
elsif method =~ /^((.+)_at)_time$/
self.send :time, $1
else
super
end
end
def date(type)
return self.instance_variable_get("@#{type.to_s}_date") if self.instance_variable_get("@#{type.to_s}_date")
if self.send type.to_sym
self.send(type.to_sym).in_time_zone(eventable.time_zone).to_date.to_s
end
end
...
I'd like to add the setters dynamically, but I'm not sure how to do so in a way that avoids ActiveRecord::UnknownAttributeError
s.
Upvotes: 0
Views: 2192
Reputation: 15771
If I understand you correctly, try:
# in SomeModel
def self.new_setter(setter_name, &block)
define_method("#{setter_name}=", &block)
attr_accessible setter_name
end
Usage:
SomeModel.new_setter(:blah) {|val| self.id = val }
SomeModel.new(blah: 5) # => SomeModel's instance with id=5
# or
@sm = SomeModel.new
@sm.blah = 5
Upvotes: 1
Reputation: 80041
I think this would work:
def method_missing(method, *args, &block)
super unless method =~ /_date$/
class_eval { attr_accessor method }
super
end
Upvotes: 3
Reputation: 864
Could you just use virtual attributes?
Class Whatever < ApplicationModel
attr_accessor :started_at_date
attr_accessor :completed_at_date
#if you want to include these attributes in mass-assignment
attr_accessible :started_at_date
attr_accessible :completed_at_date
end
When you need to access the attributes later instead of calling @started_at_date you would call self.started_at_date, etc.
Upvotes: 1