Rails 3 - создание собственной модели и работа с другими - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть две таблицы для проверки просмотров (посещения страницы) - просмотров фото (PhotoView) в галерее и фотографов (PhotographerView).Поскольку эти две модели (и таблицы) одинаковы, я хочу создать для них модель - что-то вроде:

class Func < ActiveRecord::Base

  def self.check_views(model_view, data)
    last_view = model_viewView.where('ip_address = ? AND request_url = ?', request.remote_ip, request.url).order('created_at DESC').first

    unless last_view
      model_view+View.new(...).save
      model_view.increment_counter(:views, data.id)

    else
      if (DateTime.now - last_view.created_at.to_datetime) > 1.day
        model_view+View.new(...).save
        model_view.increment_counter(:views, data.id)
      end
    end #comparing dates
  end
end

и вызвать этот метод как:

@photo = Photo.find(params[:id])
Func.check_views('Photo', @photo)

Когда япопробуйте использовать его, как описано выше, я получу ошибку неопределенный метод `check_views 'для Func (таблица не существует): Класс

Не могли бы вы помочь мне, какзаставить это работать?Спасибо

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Вы можете использовать ActiveRecord::Concern и модули для перемещения общих функций в одно место следующим образом:

module CheckViews

  extend ActiveSupport::Concern


  module ClassMethods
    # all class methods go here, if you don't have any just leave it blank
  end

  def check_views(data)
    last_view = where('ip_address = ? AND request_url = ?', request.remote_ip, request.url).order('created_at DESC').first

    unless last_view
      @@views_class.new(...).save
      increment_counter(:views, data.id)

    else
      if (DateTime.now - last_view.created_at.to_datetime) > 1.day
        @@views_class.new(...).save
        increment_counter(:views, data.id)
      end
    end #comparing dates
  end

end


class Photo < ActiveRecord::Base
  include CheckViews

end  

Теперь вы можете делать следующее:

@photo = Photo.find(params[:id])
@photo.check_views
1 голос
/ 22 февраля 2012

Я бы очень хотел сделать это как модуль, расширяющий классы, которым нужна функциональность Views. Что-то вроде следующего должно работать; но он полностью не проверен и совершенно не похож на все, что я когда-либо делал раньше, поэтому может быть полностью ошибочным. Справедливое предупреждение.

module CheckViews

  def self.extended(host_class)
    host_class.class_variable_set("@@views_class", "#{host_class}View".constantize)
  end

  def check_views(data)
    last_view = where('ip_address = ? AND request_url = ?', request.remote_ip, request.url).order('created_at DESC').first

    unless last_view
      @@views_class.new(...).save
      increment_counter(:views, data.id)

    else
      if (DateTime.now - last_view.created_at.to_datetime) > 1.day
        @@views_class.new(...).save
        increment_counter(:views, data.id)
      end
    end #comparing dates
  end
end

class Photo < ActiveRecord::Base
  extend CheckViews
  ...
end

(extend добавляет все методы экземпляра цели Module в качестве методов класса вызывающего класса; таким образом, Photo получает Photo.check_views(data), а self в этой функции является классом Photo.)

...