Rails basics - counting most used values
A widget has_one type, and type has_many widgets. I'd like to count which types are the most commonly assigned to my widgets (top 3 used).
What would be the best way 开发者_Python百科to accomplish this?
The way I have the database structured is the widgets table has a type_id, which is assigned by a select when creating the widget.
I imagined that this would be a method I'd define in the model of my widget.rb, since I'd need to collect all my widgets before counting up the types and giving them a "score" if you will.
I'm wondering if there is an easier way to figure out which of the types are most used - my goal is to return them from the method in the model, which is created as an array and assigned to a variable in the controller.
The view them pulls the top three by simply calling first three values of the array.
I think your widgets should belongs_to type, as the widget table would be the one holding the type_id. Next, I suggest using the Rails counter_cache (scroll down to the options).
First you would run a migration like:
class AddTypesWidgetsCount < ActiveRecord::Migration
def self.up
change_table :types do |t|
t.integer :widgets_count
end
end
def self.down
change_table :types do |t|
t.remove :widgets_count
end
end
end
Then add the :counter_cache => true
attribute to your belongs_to method.
class Widget < ActiveRecord::Base
belongs_to :type, :counter_cache => true
end
After that you can create a scope that sorts types by widgets_count
. Your type model could look something like:
class Widget < ActiveRecord::Base
has_many :widgets
named_scope :top_three, :order => 'widgets_count DESC', :limit => 3
end
Then you can call Type.top_three
to get the top three types by widget count. Or, without the named scope, you can call something like Type.find(:order => 'widgets_count DESC', :limit => 3)
, but the named scope will allow chaining.
精彩评论