Ответ 1
UPDATE
Код в этом ответе был использован в качестве основы для http://github.com/charlotte-ruby/impressionist Попробуйте
Вероятно, вам понадобится меньше времени, чтобы закодировать это в своем приложении, а затем вытащить данные из Google Analytics с помощью их API. Эти данные, скорее всего, будут более точными, и вам не придется полагаться на внешнюю зависимость. Также у вас будет статистика в реальном времени, а не в ожидании 12 часов в данных Google Analytics. request.remote_ip
работает очень хорошо. Вот решение, использующее полиморфизм. Обратите внимание, что этот код не проверен, но он должен быть закрыт.
Создайте новую модель/перенос для хранения просмотров страниц (показов):
class Impressions < ActiveRecord::Base
belongs_to :impressionable, :polymorphic=>true
end
class CreateImpressionsTable < ActiveRecord::Migration
def self.up
create_table :impressions, :force => true do |t|
t.string :impressionable_type
t.integer :impressionable_id
t.integer :user_id
t.string :ip_address
t.timestamps
end
end
def self.down
drop_table :impressions
end
end
Добавьте строку в модель статьи для ассоциации и добавьте метод для возврата количества показов:
class Article < ActiveRecord::Base
has_many :impressions, :as=>:impressionable
def impression_count
impressions.size
end
def unique_impression_count
# impressions.group(:ip_address).size gives => {'127.0.0.1'=>9, '0.0.0.0'=>1}
# so getting keys from the hash and calculating the number of keys
impressions.group(:ip_address).size.keys.length #TESTED
end
end
Создайте файл before_filter для article_controller в действии show:
before_filter :log_impression, :only=> [:show]
def log_impression
@article = Article.find(params[:id])
# this assumes you have a current_user method in your authentication system
@article.impressions.create(ip_address: request.remote_ip,user_id:current_user.id)
end
Затем вы просто вызываете unique_impression_count в своем представлении
<%[email protected]_impression_count %>
Если вы используете это в кучке моделей, вы можете захотеть его СУХОЙ. Поместите параметр before_filter в application_controller и используйте что-то динамическое, например:
impressionable_class = controller_name.gsub("Controller","").constantize
impressionable_instance = impressionable_class.find(params[:id])
impressionable_instance.impressions.create(ip_address:request.remote_ip,user_id:current_user.id)
А также переместите код в модели Article в модуль, который будет включен в ActiveRecord:: Base. Вы можете включить отправку в config/initializer.. или если вы хотите сходить с ума, просто превратите все это в движок rails, чтобы вы могли повторно использовать его в других приложениях.
module Impressionable
def is_impressionable
has_many :impressions, :as=>:impressionable
include InstanceMethods
end
module InstanceMethods
def impression_count
impressions.size
end
def unique_impression_count
impressions.group(:ip_address).size
end
end
end
ActiveRecord::Base.extend Impressionable