I'm trying to add some custom methods to ActiveRecord. I want to add a *_after
and *_before
scopes for every date
field of a model so I can do something like this:
User.created_at_after(DateTime.now - 3.days).created_at_before(DateTime.now)
I've followed the solution explained here Rails extending ActiveRecord::Base but when I execute the rails console and try to call the methods I get an undefined method
error.
Here's my code:
# config/initializers/active_record_date_extension.rb
require "active_record_date_extension"
# lib/active_record_date_extension.rb
module ActiveRecordDateExtension
extend ActiveSupport::Concern
included do |base|
base.columns_hash.each do |column_name,column|
if ["datetime","date"].include? column.type
base.define_method("#{column_name}_after") do |date|
where("#{column_name} > ?", date)
end
base.define_method("#{column_name}_before") do |date|
where("#{column_name} < ?", date)
end
end
end
end
end
Rails.application.eager_load!
ActiveRecord::Base.descendants.each do |model|
model.send(:include, ActiveRecordDateExtension)
end
What am I doing wrong?
ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.
Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.
Using Rails 4.1.9 and Ruby 2.2.1, I noticed a few issues with the code above.
column.type
with strings, and Rails returns symbols for that attribute.base.define_method
is trying to call a private method, you can get around that with send
This is the tweaked code
module ActiveRecordDateExtension
extend ActiveSupport::Concern
included do |base|
base.columns_hash.each do |column_name,column|
if [:datetime, :date].include? column.type
base.class.send(:define_method, "#{column_name}_after") do |date|
where("#{column_name} > ?", date)
end
base.class.send(:define_method, "#{column_name}_before") do |date|
where("#{column_name} < ?", date)
end
end
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With