English 中文(简体)
Rails Model With Aggregrate Data (not backed by a table)
原标题:

Id like to create a model in rails that does not correlate to a table in the database. Instead the model should dynamically pull aggregrate data about other models.

Example:

I have a Restaurant model stored in the restaurants table in the DB. Id like to have a RestaurantStats model where i can run a RestaurantStats.find_total_visitors, or RestaurantStats.find_time_spent etc... on it and it returns a set of RestaurantStats models each with:

[:restaurant_id, :stat_value]

Obviously in each find... method that stat_value will mean something different (for find_time_spent it will be seconds spent, for find_total_visitors it will be number of visitors). The idea will be to return the top 100 restaurants by time spent, or total visitors.

So far im creating a model (not inherited from ActiveRecord)

class RestaurantStats 
   attr_reader :restaurant_id
   attr_reader :stat_value

   def self.find_total_visitors ... 
   def self.find_time_spent ...
end

The question is how do define the find_total_visitors, find_time_spent functions in a rails y way so that it will populate the restaurant_id, stat_value fields?

最佳回答

Are you sure you don t just want these to be methods on Restaurant?

class Restaurant < ActiveRecord::Base
  has_many :visitors

  def total_visitors
    visitors.count # Or whatever
  end

  def time_spent
    visitors.average(:visit_time) # Or whatever      
  end
end
问题回答

Set the values using self.(fieldname) and then save those value (after running a find or build).

Given that you want to sort your searches on statistics, adding counter caches to the Restaurant model looks like your best option.

In the case of total visitors this is simple. In the case of total time_spent, it will be a little more complex, but still not unmanageable. If you re looking for an average then things get a little more complicated.

Here s the code required to add counter caches to your restaurant model. Notice that most of new model code is in the visitor s model.

Add new columns to Restaurant via migration:

class AddCounterCaches < ActiveRecord::Migration
  def self.up
    add_column :restaurants, :visitors_count, :integer, :default => 0
    add_column :restaurants, :total_time_spent, :integer, :default => 0
    Restaurant.reset_column_information
    Restaurant.find(:all).each do |r|
      count = r.visitors.length
      total = r.visitors.inject(0) {|sum, v| sum + v.time_spent}
      average = count == 0 ? 0 : total/count
      r.update_counters r.id, :visitors_count => count
       :total_time_spent => total, :average_time_spent => average
    end
  end

  def self.down
    remove_column :restaurants, :visitors_count        
    remove_column :restaurants, :total_time_spent
  end
end

Update visitor model to update counter caches

class Vistor < ActiveRecord::Base
  belongs_to :restaurant, :counter_cache => true 

  after_save :update_restaurant_time_spent, 
    :if => Proc.new {|v| v.changed.include?("time_spent")}

  def :update_restaurant_time_spent
    difference = changes["time_spent"].last - changes["time_spent"].first
    Restaurant.update_counters(restaurant_id, :total_time_spent => difference)       
    restaurant.reload   
    avg = restaurant.visitors_count == 0 ? 
      0 : restaurant.total_time_spent / restaurant.visitors_count
    restaurant.update_attribute(:average_time_spent, avg)
  end     
end 

N.B. Code hasn t been tested, so it may contain minor errors.

Now you can sort by these columns, create named scopes that include them or use them in your methods.





相关问题
rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

SSL slowness in EC2

We ve deployed our rails app to EC2. In our setup, we have two proxies on small instances behind round-robin DNS. These run nginx load balancers for a dynamically growing and shrinking farm of web ...

Auth-code with A-Za-z0-9 to use in an URL parameter

As part of a web application I need an auth-code to pass as a URL parameter. I am currently using (in Rails) : Digest::SHA1.hexdigest((object_id + rand(255)).to_s) Which provides long strings like : ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

activerecord has_many :through find with one sql call

I have a these 3 models: class User < ActiveRecord::Base has_many :permissions, :dependent => :destroy has_many :roles, :through => :permissions end class Permission < ActiveRecord::...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签