Posted by pratik
on Thursday, November 01
This question is asked quite a few times in #rubyonrails
When your models look like :
1
2
3
4
5
6
7
|
class User < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :user
end |
How do you find all the users with at least ‘n’ number of items ?
Here’s how :
|
User.find :all, :joins => "INNER JOIN items ON items.user_id = users.id", :select => "users.*, count(items.id) items_count", :group => "items.user_id HAVING items_count > 5" |
This will give you all the users with at least 5 items.
The statement is using INNER JOIN to eliminate users with no items. Also, in :select, there is count(items.id) aliased items_count and in :group is items.user_id. This will group items by user_id and also count number of items per user. Now, database requires HAVING clause when you want to supply conditions for group functions ( items_count in our case ). ActiveRecord, as of now, doesn’t provide :having key for find(). Hence, we need to use a very little hack ( more like workaround ) to overcome that and supply HAVING clause in :group key.
May be someone interested can submit a patch for :having key in AR finders.
Posted by pratik
on Thursday, October 18
For fuck’s sake, STOP asking this question in IRC
You’re completely/totally/fucking wrong if you want to access sessions, params, cookies, etc. in your Models.
You can’t get more wrong than this in rails world probably. But some people just don’t get it. So if you must, this is how you can do it ( I’d suggest you go back to PHP or whatever ) :
Add this code at the bottom of your application.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
class ApplicationController < ActionController::Base
# Your existing stuff
around_filter :you_dont_have_bloody_clue
protected
def you_dont_have_bloody_clue
klasses = [ActiveRecord::Base, ActiveRecord::Base.class]
methods = ["session", "cookies", "params", "request"]
methods.each do |shenanigan|
oops = instance_variable_get(:"@_#{shenanigan}")
klasses.each do |klass|
klass.send(:define_method, shenanigan, proc { oops })
end
end
yield
methods.each do |shenanigan|
klasses.each do |klass|
klass.send :remove_method, shenanigan
end
end
end
end |
Again, do it if you wish, just don’t ask anyone how to do it ever again!