Alvin Lau
Alvin Lau

Reputation: 101

Rails custom model method in where query

In my rails app I have defined in the Kid model a calculation based on the fields from the Kids DB. the method is as follows:

def flip_date 
  self.dob.advance(months: 10) 
end

I want to use this in my controller as I have a method where I am defining something as follows:

new_kids = Kid.where(discharge_date: nil).where('flip_date > ?', Date.current.advance(year: 1).beginning_of_year)

However I keep getting the following error:

SQLite3::SQLException: no such column: flip_date: SELECT "kids".* FROM "kids" WHERE "kids"."discharge_date" IS NULL AND (flip_date < '2017-01-01')

Any ideas on how can I make this work? All help is appreciated!

Upvotes: 2

Views: 7975

Answers (3)

Lee McAlilly
Lee McAlilly

Reputation: 9316

This example doesn't respond to your specific code, but to the extent it helps someone else with a similar question, here's a very simple example of how .select can be really handy:

@expired_memberships = User.select{|u| u.membership_expired_yesterday?}

In that example you've looped through all your Users and filtered them based on a custom method you defined on the User model (membership_expired_yesterday?). Now you can easily do stuff with that collection like this example in a mailer:

@expirations.each do |user|
  MembershipExpirationMailer.with(user: user).first_reminder.deliver_now
end

Upvotes: 0

Michael
Michael

Reputation: 11

The select method (http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/select) works great if you are okay with the return being an Array.

I am still looking for a way to do this with an ActiveRecord_Relation return.

If others know how to do this, it would be much appreciated if you can share.

Upvotes: 0

dnsh
dnsh

Reputation: 3633

If you really want to use model methods take a look at http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/select

For your case:

new_kids = Kid.where(discharge_date: nil).select{|k| k.flip_date > Date.current.advance(year: 1).beginning_of_year}

But select method takes every object in memory before returning final result. Hence I will advise to use normal where clause and instead of flip_date take dob (which is a column in database) in consideration.

Like this

new_kids = Kid.where(discharge_date: nil).where('dob > ?', <date criteria>)

Upvotes: 3

Related Questions