5

Has anyone been able to find a way to search a calculated field using metawhere or metasearch in rails 3? I can search any field but calculated fields. There has to be a way. For anyone not familiar with metasearch or metawhere here is a railscast.

http://railscasts.com/episodes/251-metawhere-metasearch

user893447
  • 71
  • 1
  • 3
  • Do you mean fields that are not stored in the database and defined in the model instead? – Devin M Aug 17 '11 at 03:23
  • yes, please explain what you mean by calculated? – Vlad Khomich Aug 17 '11 at 05:24
  • by calculated fields, do you mean virtual parameters defined in model, calculated from database table columns? I dont think u can search those using these gems for that, as the search will ultimately break down to database level. – rubyprince Aug 17 '11 at 08:46
  • I do mean fields that are defined in the model. They are actual stored fields in my database, but I have a method in the model that is populating it with the product of several other fields. Is there any way to search on those? I know they can be sorted in the controller by using the below statement in the controller @user = User.find(:all).sort_by(&:age) - in this case, age could be date.today - birthday – user893447 Aug 17 '11 at 12:15

1 Answers1

1

Metawhere (now Squeel) extends ActiveRecord's implementation of Arel which is a SQL generator. That means it will turn some statement in SQL e.g :

@user.order("birthday").to_sql #=> SELECT users.* FROM users ORDER BY birthday

When you do User.find(:all).sort_by(&:age) you are working on a the result of find(:all), an Array, and the sorting is done in Ruby with Enumerable which is slower and has nothing to do with the database.

So no, you cannot use Metawhere on

def age
  date.today - birthday
end

unless you store the result in the database.

However you can use the SQL statements like COUNT AVG MAX etc with GROUP and HAVING to do calculation directly on the database.

User.select("users.*, COUNT(user_id) AS vote_num").joins(:votes).group("user_id")

charlysisto
  • 3,700
  • 17
  • 30