Skip to content

Instantly share code, notes, and snippets.

@utx0
Created May 29, 2013 06:57
Show Gist options
  • Save utx0/5668432 to your computer and use it in GitHub Desktop.
Save utx0/5668432 to your computer and use it in GitHub Desktop.
model_in_question
class Product < ActiveRecord::Base
include ActionView::Helpers
MASS_ASSIGNABLE_ATTRIBUTES = [:authority, :category_id, :category_ids, :country_id, :description, :duration,
:long_description, :name, :people_attributes, :permission, :poster, :poster_cache, :product_countries_attributes,
:product_id, :product_people_attributes, :region_ids, :user_attributes, :year_of_completion, :terms_and_conditions]
attr_accessible *MASS_ASSIGNABLE_ATTRIBUTES
attr_accessible *MASS_ASSIGNABLE_ATTRIBUTES, as: :admin
attr_accessible :assets_attributes, :cash_value, :product_type, :recommended, :status, :tags_autocomplete, :user_id,
as: :admin
scope :top, where(:product_id => nil)
scope :published, where(:status => 'published')
scope :newly_available, published.order('created_at DESC')
scope :most_popular, published.joins('LEFT JOIN orders ON products.id = orders.product_id').group('products.id').order('count(orders.product_id) DESC')
scope :recommended, published.where(:recommended => true)
scope :years, published.select(:year_of_completion).order("year_of_completion DESC").group(:year_of_completion)
has_many :product_people, :dependent => :destroy
has_many :people, :through => :product_people
has_many :product_tags, :dependent => :destroy
has_many :tags, :through => :product_tags
has_many :product_countries, :dependent => :delete_all
has_many :countries, :through => :product_countries
has_many :product_regions, :dependent => :destroy
has_many :regions, :through => :product_regions
has_many :product_categories, :dependent => :destroy
has_many :categories, :through => :product_categories, :foreign_key => :category_id # genres
has_many :assets, :dependent => :destroy
has_many :reviews
has_many :orders
has_many :products #TODO Review why this is required?
belongs_to :product #TODO Review why this is required?
belongs_to :country
belongs_to :category
belongs_to :user
accepts_nested_attributes_for :assets, :allow_destroy => true
accepts_nested_attributes_for :people
accepts_nested_attributes_for :product_people, :allow_destroy => true
accepts_nested_attributes_for :product_countries, :allow_destroy => true
accepts_nested_attributes_for :product_regions, :allow_destroy => true
accepts_nested_attributes_for :user
# VALIDATIONZOR!!!
validates :name, :presence => {:message => "required"}
validates :country_id, :presence => {:message => "required"}
validates :duration, :presence => {:message => "required"}
#validates :poster, :presence => {:message => "required (max 220 x 150px)"}
validates :description, :presence => {:message => "required"}
validates :year_of_completion, :presence => {:message => "required"}
validates :authority, :acceptance => true, :unless => :blank?
validates :terms_and_conditions, :acceptance => true, :unless => :blank?
validates :description, :length => { :maximum => 230, :message => "synopsis cannot be longer than 230 characters in length" }, :if => :description?
validate :check_permission_setting
validate :check_region_ids
#If there's no cash_value at all, it doesn't require one. ActiveAdmin edit it is necessary.
validates :cash_value, :presence => {:message => "required"}, :unless => "cash_value.blank?"
validates :categories, :presence => {:message => "required"}
mount_uploader :poster, PosterUploader
STATUS = %w[submitted published]
#Stringex configuration
acts_as_url :name
#For stringex
def to_param
url
end
# custom fields
def orders_units
attributes['orders_units']
end
def orders_total
attributes['orders_total']
end
def check_permission_setting
unless permission.nil?
if permission != true
errors.add(:permission, "please provide permission to sell in the selected regions")
end
end
end
def check_region_ids
if region_ids.empty?
errors.add(:countries, "- select at least one country")
end
end
#virtual attribute to set Tags for this Product. Parameters: comma delimited string
# eg. "Dogs, Cats, Birds"
def tags_autocomplete=(tags_autocomplete)
tags_array = Array.new
submitted_tags = tags_autocomplete.split(',').delete_if(&:empty?)
submitted_tags.each do |t|
stripped = t.strip
unless stripped.blank?
this_tag = Tag.find_or_create_by_name(stripped)
tags_array.push(this_tag) unless tags_array.include?(this_tag) #add to array to be saved
end
end
self.tags = tags_array
end
#Get an array of Tag objects that are associated with this Product
def tags_autocomplete
tags_string = String.new
self.tags.each do |t|
tags_string << t.name
tags_string << ', '
end
@tags_autocomplete = tags_string
end
def related_videos
return self.assets.trailers
end
def self.by_category(categories)
joins(:product_categories).where('product_categories.category_id' => categories)
end
def self.by_year(year)
if year
return Product.where(:year_of_completion => year).order(:year_of_completion)
end
end
def self.by_country(country)
return Product.where(:country_id => country)
end
# method to define whether or not a user has access to view a particular
# product. Returns a boolean value based on the result.
def can_play?(user_id)
Order.where(:user_id => user_id, :product_id => id).where('created_at > ?', Time.now - 2.days).count > 0
end
# determines whether or not a user can actually purchase this item. If, for
# example, the user is outside the allowed countries, then they cannot purchase
# nor watch this item.
def can_purchase?(country_id)
ProductRegion.where(:product_id => id, :region_id => country_id).count > 0
end
def has_video?
assets.each do |a|
return true if a.asset_type == 'video'
end
return false
end
def has_trailer?
assets.each do |a|
return true if a.asset_type == 'trailer'
end
return false
end
def has_role?(role)
people.each do |p|
if role != 'Cast & crew'
return true if p.role.title == role
else
return true if p.role.title != 'Filmmaker' && p.role.title != 'Producer' && p.role.title != 'Director'
end
end
return false
end
def update_rating
update_attribute(:rating, reviews.average(:rating))
end
def is_favourite?(user)
if user
if Favourite.where(:user_id => user.id, :product_id => id).count > 0
return true
end
end
return false
end
# paypal requires price to be in cents
def paypal_value
cash_value * 100
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment