diff --git a/lib/generators/ratyrate/ratyrate_generator.rb b/lib/generators/ratyrate/ratyrate_generator.rb index 9b673e7..80ecf5f 100644 --- a/lib/generators/ratyrate/ratyrate_generator.rb +++ b/lib/generators/ratyrate/ratyrate_generator.rb @@ -5,19 +5,19 @@ class RatyrateGenerator < ActiveRecord::Generators::Base source_root File.expand_path('../templates', __FILE__) - desc "copying jquery.raty files to assets directory ..." - def copying - copy_file 'jquery.raty.js', 'app/assets/javascripts/jquery.raty.js' - copy_file 'star-on.png', 'app/assets/images/star-on.png' - copy_file 'star-off.png', 'app/assets/images/star-off.png' - copy_file 'star-half.png', 'app/assets/images/star-half.png' - copy_file 'mid-star.png', 'app/assets/images/mid-star.png' - copy_file 'big-star.png', 'app/assets/images/big-star.png' - copy_file 'cancel-on.png', 'app/assets/images/cancel-on.png' - copy_file 'cancel-off.png', 'app/assets/images/cancel-off.png' - copy_file 'ratyrate.js.erb', 'app/assets/javascripts/ratyrate.js.erb' - copy_file 'rater_controller.rb', 'app/controllers/rater_controller.rb' - end + # desc "copying jquery.raty files to assets directory ..." + # def copying + # copy_file 'jquery.raty.js', 'app/assets/javascripts/jquery.raty.js' + # copy_file 'star-on.png', 'app/assets/images/star-on.png' + # copy_file 'star-off.png', 'app/assets/images/star-off.png' + # copy_file 'star-half.png', 'app/assets/images/star-half.png' + # copy_file 'mid-star.png', 'app/assets/images/mid-star.png' + # copy_file 'big-star.png', 'app/assets/images/big-star.png' + # copy_file 'cancel-on.png', 'app/assets/images/cancel-on.png' + # copy_file 'cancel-off.png', 'app/assets/images/cancel-off.png' + # copy_file 'ratyrate.js.erb', 'app/assets/javascripts/ratyrate.js.erb' + # copy_file 'rater_controller.rb', 'app/controllers/rater_controller.rb' + # end desc "model is creating..." def create_model @@ -26,31 +26,17 @@ def create_model class_collisions 'Rate' template 'model.rb', File.join('app/models', "rate.rb") template 'cache_model.rb', File.join('app/models', "rating_cache.rb") - template 'average_cache_model.rb', File.join('app/models', "average_cache.rb") - template 'overall_average_model.rb', File.join('app/models', "overall_average.rb") + template 'rating_average_model.rb', File.join('app/models', "rating_average.rb") end def add_rate_path_to_route route "post '/rate' => 'rater#create', :as => 'rate'" end - desc "cacheable rating average migration is creating ..." - def create_cacheable_migration - migration_template "cache_migration.rb", "db/migrate/create_rating_caches.rb" - end - - desc "migration is creating ..." - def create_ratyrate_migration + desc "copy migrations" + def create_migrations migration_template "migration.rb", "db/migrate/create_rates.rb" - end - - desc "average caches migration is creating ..." - def create_average_caches_migration - migration_template "average_cache_migration.rb", "db/migrate/create_average_caches.rb" - end - - desc "overall averages migration is creating ..." - def create_overall_averages_migration - migration_template "overall_average_migration.rb", "db/migrate/create_overall_averages.rb" + migration_template "cache_migration.rb", "db/migrate/cache_migration.rb" + migration_template "rating_average_migration.rb", "db/migrate/create_rating_averages.rb" end end diff --git a/lib/generators/ratyrate/templates/average_cache_migration.rb b/lib/generators/ratyrate/templates/average_cache_migration.rb deleted file mode 100644 index 317d571..0000000 --- a/lib/generators/ratyrate/templates/average_cache_migration.rb +++ /dev/null @@ -1,17 +0,0 @@ -class CreateAverageCaches < ActiveRecord::Migration - - def self.up - create_table :average_caches do |t| - t.belongs_to :rater - t.belongs_to :rateable, :polymorphic => true - t.float :avg, :null => false - t.timestamps - end - end - - def self.down - drop_table :average_caches - end - -end - diff --git a/lib/generators/ratyrate/templates/average_cache_model.rb b/lib/generators/ratyrate/templates/average_cache_model.rb deleted file mode 100644 index b4d2da1..0000000 --- a/lib/generators/ratyrate/templates/average_cache_model.rb +++ /dev/null @@ -1,4 +0,0 @@ -class AverageCache < ActiveRecord::Base - belongs_to :rater, :class_name => "<%= file_name.classify %>" - belongs_to :rateable, :polymorphic => true -end diff --git a/lib/generators/ratyrate/templates/cache_migration.rb b/lib/generators/ratyrate/templates/cache_migration.rb index 8eb063a..dbd9097 100644 --- a/lib/generators/ratyrate/templates/cache_migration.rb +++ b/lib/generators/ratyrate/templates/cache_migration.rb @@ -1,19 +1,14 @@ class CreateRatingCaches < ActiveRecord::Migration - def self.up - create_table :rating_caches do |t| - t.belongs_to :cacheable, :polymorphic => true - t.float :avg, :null => false - t.integer :qty, :null => false - t.string :dimension - t.timestamps - end - - add_index :rating_caches, [:cacheable_id, :cacheable_type] - end - - def self.down - drop_table :rating_caches + def change + create_table :rating_caches do |t| + t.belongs_to :cacheable, polymorphic: true + t.float :avg, null: false + t.integer :qty, null: false + t.string :dimension + t.timestamps end + add_index :rating_caches, [:cacheable_id, :cacheable_type] + end end \ No newline at end of file diff --git a/lib/generators/ratyrate/templates/cache_model.rb b/lib/generators/ratyrate/templates/cache_model.rb index 1a2b2eb..79e1b22 100644 --- a/lib/generators/ratyrate/templates/cache_model.rb +++ b/lib/generators/ratyrate/templates/cache_model.rb @@ -1,3 +1,3 @@ class RatingCache < ActiveRecord::Base - belongs_to :cacheable, :polymorphic => true + belongs_to :cacheable, polymorphic: true end \ No newline at end of file diff --git a/lib/generators/ratyrate/templates/overall_average_migration.rb b/lib/generators/ratyrate/templates/overall_average_migration.rb deleted file mode 100644 index 8b7ecaa..0000000 --- a/lib/generators/ratyrate/templates/overall_average_migration.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreateOverallAverages < ActiveRecord::Migration - - def self.up - create_table :overall_averages do |t| - t.belongs_to :rateable, :polymorphic => true - t.float :overall_avg, :null => false - t.timestamps - end - end - - def self.down - drop_table :overall_averages - end - -end - diff --git a/lib/generators/ratyrate/templates/overall_average_model.rb b/lib/generators/ratyrate/templates/overall_average_model.rb deleted file mode 100644 index 16acb68..0000000 --- a/lib/generators/ratyrate/templates/overall_average_model.rb +++ /dev/null @@ -1,4 +0,0 @@ -class OverallAverage < ActiveRecord::Base - belongs_to :rateable, :polymorphic => true -end - diff --git a/lib/generators/ratyrate/templates/rating_average_migration.rb b/lib/generators/ratyrate/templates/rating_average_migration.rb new file mode 100644 index 0000000..80732a6 --- /dev/null +++ b/lib/generators/ratyrate/templates/rating_average_migration.rb @@ -0,0 +1,16 @@ +class CreateRatingAverages < ActiveRecord::Migration + + def change + create_table :rating_averages do |t| + t.belongs_to :rateable, polymorphic: true + t.float :avg, null:false + t.belongs_to :rater + + t.timestamps + end + + add_index :rating_averages, [:rateable_id, :rateable_type] + add_index :rating_averages, [:rateable_id, :rateable_type, :rater_id] + end +end + diff --git a/lib/generators/ratyrate/templates/rating_average_model.rb b/lib/generators/ratyrate/templates/rating_average_model.rb new file mode 100644 index 0000000..6270c6b --- /dev/null +++ b/lib/generators/ratyrate/templates/rating_average_model.rb @@ -0,0 +1,5 @@ +class RatingAverage < ActiveRecord::Base + belongs_to :rateable, polymorphic: true + belongs_to :rater, class_name: "<%= file_name.classify %>" +end + diff --git a/lib/ratyrate.rb b/lib/ratyrate.rb index 3fb3e97..5202878 100644 --- a/lib/ratyrate.rb +++ b/lib/ratyrate.rb @@ -1,6 +1,7 @@ require "ratyrate/version" require "ratyrate/model" -require "ratyrate/helpers" +require "ratyrate/helpers" +require "ratyrate/engine" module Ratyrate diff --git a/lib/ratyrate/engine.rb b/lib/ratyrate/engine.rb new file mode 100644 index 0000000..dece706 --- /dev/null +++ b/lib/ratyrate/engine.rb @@ -0,0 +1,7 @@ +module RatyRate + class Engine < ::Rails::Engine + initializer 'ratyrate.load_static_assets' do |app| + app.middleware.use ::ActionDispatch::Static, "#{root}/vendor" + end + end +end \ No newline at end of file diff --git a/lib/ratyrate/helpers.rb b/lib/ratyrate/helpers.rb index fa5681c..ec5af42 100644 --- a/lib/ratyrate/helpers.rb +++ b/lib/ratyrate/helpers.rb @@ -1,142 +1,96 @@ module Helpers def rating_for(rateable_obj, dimension=nil, options={}) - cached_average = rateable_obj.average dimension - avg = cached_average ? cached_average.avg : 0 - - star = options[:star] || 5 - enable_half = options[:enable_half] || false - half_show = options[:half_show] || false - star_path = options[:star_path] || "/assets" - star_on = options[:star_on] || "star-on.png" - star_off = options[:star_off] || "star-off.png" - star_half = options[:star_half] || "star-half.png" - cancel = options[:cancel] || false - cancel_place = options[:cancel_place] || "left" - cancel_hint = options[:cancel_hint] || "Cancel current rating!" - cancel_on = options[:cancel_on] || "cancel-on.png" - cancel_off = options[:cancel_off] || "cancel-off.png" - noRatedMsg = options[:noRatedMsg] || "I'am readOnly and I haven't rated yet!" - # round = options[:round] || { down: .26, full: .6, up: .76 } - space = options[:space] || false - single = options[:single] || false - target = options[:target] || '' - targetText = options[:targetText] || '' - targetType = options[:targetType] || 'hint' - targetFormat = options[:targetFormat] || '{score}' - targetScore = options[:targetScore] || '' + star = options[:star] || 5 + enable_half = options[:enable_half] || false + half_show = options[:half_show] || false + star_path = options[:star_path] || "/assets" + star_on = asset_path(options[:star_on] || "star-on.png") + star_off = asset_path(options[:star_off] || "star-off.png") + star_half = asset_path(options[:star_half] || "star-half.png") + cancel = options[:cancel] || false + cancel_place = options[:cancel_place] || "left" + cancel_hint = options[:cancel_hint] || "Cancel current rating!" + cancel_on = asset_path(options[:cancel_on] || "cancel-on.png") + cancel_off = asset_path(options[:cancel_off] || "cancel-off.png") + no_rated_message = options[:no_rated_message] || "I'am readOnly and I haven't rated yet!" + space = options[:space] || false + single = options[:single] || false + target = options[:target] || '' + target_text = options[:target_text] || '' + target_type = options[:target_type] || 'hint' + target_format = options[:target_format] || '{score}' + target_score = options[:target_score] || '' + hints = options[:hints] || ['bad', 'poor', 'regular', 'good', 'gorgeous'] disable_after_rate = options[:disable_after_rate] && true disable_after_rate = true if disable_after_rate == nil - if disable_after_rate - readonly = !(current_user && rateable_obj.can_rate?(current_user, dimension)) - else - readonly = !current_user || false - end + readonly = if options.has_key?(:read_only) + options[:read_only] == true + elsif disable_after_rate + !(current_user && rateable_obj.can_rate?(current_user, dimension)) + else + false + end - if options[:imdb_avg] && readonly - content_tag :div, '', :style => "background-image:url(/assets/mid-star.png);width:61px;height:57px;margin-top:10px;" do - content_tag :p, avg, :style => "position:relative;font-size:.8rem;text-align:center;line-height:60px;" - end - else - content_tag :div, '', "data-dimension" => dimension, :class => "star", "data-rating" => avg, - "data-id" => rateable_obj.id, "data-classname" => rateable_obj.class.name, - "data-disable-after-rate" => disable_after_rate, - "data-readonly" => readonly, - "data-enable-half" => enable_half, - "data-half-show" => half_show, - "data-star-count" => star, - "data-star-path" => star_path, - "data-star-on" => star_on, - "data-star-off" => star_off, - "data-star-half" => star_half, - "data-cancel" => cancel, - "data-cancel-place" => cancel_place, - "data-cancel-hint" => cancel_hint, - "data-cancel-on" => cancel_on, - "data-cancel-off" => cancel_off, - "data-no-rated-message" => noRatedMsg, - # "data-round" => round, - "data-space" => space, - "data-single" => single, - "data-target" => target, - "data-target-text" => targetText, - "data-target-type" => targetType, - "data-target-format" => targetFormat, - "data-target-score" => targetScore - end + starts = if options[:stars] + options[:stars].to_s + elsif user = options[:user] + rating = user.ratings_given.where(rateable: rateable_obj, dimension: dimension).first + rating ? rating.stars.to_s : 0 + elsif dimension.present? + cached_average = rateable_obj.average dimension + cached_average ? cached_average.avg.to_s : 0 + end + + + content_tag :div, '', class: 'star', data: { + dimension: dimension, + rating: starts, + id: rateable_obj.id, + classname: rateable_obj.class.name, + disable_after_rate: disable_after_rate, + readonly: readonly, + enable_half: enable_half, + half_show: half_show, + star_count: star, + path: star_path, + star_on: star_on, + star_off: star_off, + star_half: star_half, + cancel: cancel, + cancel_place: cancel_place, + cancel_hint: cancel_hint, + cancel_on: cancel_on, + cancel_off: cancel_off, + no_rated_message: no_rated_message, + hints: hints, + space: space, + single: single, + target: target, + target_text: target_text, + target_type: target_type, + target_format: target_format, + target_score: target_score + } end - def imdb_style_rating_for(rateable_obj, user, options = {}) - overall_avg = rateable_obj.overall_avg(user) + def average_rating_for(rateable_obj, options = {}) + overall_avg = rateable_obj.overall_average options[:user] content_tag :div, '', :style => "background-image:url(/assets/big-star.png);width:81px;height:81px;margin-top:10px;" do - content_tag :p, overall_avg, :style => "position:relative;line-height:85px;text-align:center;" + content_tag :p, overall_avg, :style => "position:relative;line-height:85px;text-align:center;" end end - def rating_for_user(rateable_obj, rating_user, dimension = nil, options = {}) - @object = rateable_obj - @user = rating_user - @rating = Rate.find_by_rater_id_and_rateable_id_and_dimension(@user.id, @object.id, dimension) - stars = @rating ? @rating.stars : 0 - - star = options[:star] || 5 - enable_half = options[:enable_half] || false - half_show = options[:half_show] || false - star_path = options[:star_path] || "/assets" - star_on = options[:star_on] || "star-on.png" - star_off = options[:star_off] || "star-off.png" - star_half = options[:star_half] || "star-half.png" - cancel = options[:cancel] || false - cancel_place = options[:cancel_place] || "left" - cancel_hint = options[:cancel_hint] || "Cancel current rating!" - cancel_on = options[:cancel_on] || "cancel-on.png" - cancel_off = options[:cancel_off] || "cancel-off.png" - noRatedMsg = options[:noRatedMsg] || "I'am readOnly and I haven't rated yet!" - # round = options[:round] || { down: .26, full: .6, up: .76 } - space = options[:space] || false - single = options[:single] || false - target = options[:target] || '' - targetText = options[:targetText] || '' - targetType = options[:targetType] || 'hint' - targetFormat = options[:targetFormat] || '{score}' - targetScore = options[:targetScore] || '' - - disable_after_rate = options[:disable_after_rate] || false - - readonly=false - if disable_after_rate - readonly = rating_user.present? ? !rateable_obj.can_rate?(rating_user, dimension) : true - end - - content_tag :div, '', "data-dimension" => dimension, :class => "star", "data-rating" => stars, - "data-id" => rateable_obj.id, "data-classname" => rateable_obj.class.name, - "data-disable-after-rate" => disable_after_rate, - "data-readonly" => readonly, - "data-enable-half" => enable_half, - "data-half-show" => half_show, - "data-star-count" => star, - "data-star-path" => star_path, - "data-star-on" => star_on, - "data-star-off" => star_off, - "data-star-half" => star_half, - "data-cancel" => cancel, - "data-cancel-place" => cancel_place, - "data-cancel-hint" => cancel_hint, - "data-cancel-on" => cancel_on, - "data-cancel-off" => cancel_off, - "data-no-rated-message" => noRatedMsg, - # "data-round" => round, - "data-space" => space, - "data-single" => single, - "data-target" => target, - "data-target-text" => targetText, - "data-target-format" => targetFormat, - "data-target-score" => targetScore + def average_rating_for_user(rateable_obj, user, options = {}) + average_rating_for(rateable_obj, options.merge(user: user)) end + def rating_for_user(rateable_obj, rating_user, dimension = nil, options = {}) + rating_for rateable_obj, dimension, options.merge(user: rating_user) + end end class ActionView::Base diff --git a/lib/ratyrate/model.rb b/lib/ratyrate/model.rb index f966dfb..481b8ba 100644 --- a/lib/ratyrate/model.rb +++ b/lib/ratyrate/model.rb @@ -2,7 +2,7 @@ module Ratyrate extend ActiveSupport::Concern - def rate(stars, user, dimension=nil, dirichlet_method=false) + def rate(stars, user, dimension=nil) dimension = nil if dimension.blank? if can_rate? user, dimension @@ -10,34 +10,41 @@ def rate(stars, user, dimension=nil, dirichlet_method=false) r.stars = stars r.rater = user end - if dirichlet_method - update_rate_average_dirichlet(stars, dimension) - else - update_rate_average(stars, dimension) - end else update_current_rate(stars, user, dimension) end - end - def update_rate_average_dirichlet(stars, dimension=nil) - ## assumes 5 possible vote categories - dp = {1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1} - stars_group = Hash[rates(dimension).group(:stars).count.map{|k,v| [k.to_i,v] }] - posterior = dp.merge(stars_group){|key, a, b| a + b} - sum = posterior.map{ |i, v| v }.inject { |a, b| a + b } - davg = posterior.map{ |i, v| i * v }.inject { |a, b| a + b }.to_f / sum + update_rate_average(stars, dimension) + update_overall_average_rating(stars, user, dimension) + end - if average(dimension).nil? - send("create_#{average_assoc_name(dimension)}!", { avg: davg, qty: 1, dimension: dimension }) + def overall_average(user=nil) + if user.present? + average_rates_for_user(user) else - a = average(dimension) - a.qty = rates(dimension).count - a.avg = davg - a.save!(validate: false) + average_rates end end - + + def average_rates_for_user(user) + if average_rates_with_user.present? + average_rates_with_user.find_by_rater_id(user.id) + end + end + + def update_overall_average_rating(stars, user, dimension) + # We need user average rating for all dimensions as will as overall rating form all users of all dimensions ( which they have rated ) + user_average = average_rates_for_user(user) || average_rates_with_user.build(rater: user) + user_average.avg = user.ratings_given.where(rateable: self).average(:stars) + user_average.qty = user.ratings_given.where(rateable: self).count + user_average.save validate: false + + overall = average_rates || build_average_rates + overall.avg = Rate.where(rateable: self).average(:stars) + overall.qty = Rate.where(rateable: self).count + overall.save validate: false + end + def update_rate_average(stars, dimension=nil) if average(dimension).nil? send("create_#{average_assoc_name(dimension)}!", { avg: stars, qty: 1, dimension: dimension }) @@ -50,44 +57,9 @@ def update_rate_average(stars, dimension=nil) end def update_current_rate(stars, user, dimension) - current_rate = rates.where(rater_id: user.id, dimension: dimension).take + current_rate = rates(dimension).where(rater_id: user.id).take current_rate.stars = stars current_rate.save!(validate: false) - - if rates(dimension).count > 1 - update_rate_average(stars, dimension) - else # Set the avarage to the exact number of stars - a = average(dimension) - a.avg = stars - a.save!(validate: false) - end - end - - def overall_avg(user) - # avg = OverallAverage.where(rateable_id: self.id) - # #FIXME: Fix the bug when the movie has no ratings - # unless avg.empty? - # return avg.take.avg unless avg.take.avg == 0 - # else # calculate average, and save it - # dimensions_count = overall_score = 0 - # user.ratings_given.select('DISTINCT dimension').each do |d| - # dimensions_count = dimensions_count + 1 - # unless average(d.dimension).nil? - # overall_score = overall_score + average(d.dimension).avg - # end - # end - # overall_avg = (overall_score / dimensions_count).to_f.round(1) - # AverageCache.create! do |a| - # a.rater_id = user.id - # a.rateable_id = self.id - # a.avg = overall_avg - # end - # overall_avg - # end - end - - # calculate the movie overall average rating for all users - def calculate_overall_average end def average(dimension=nil) @@ -99,45 +71,52 @@ def average_assoc_name(dimension = nil) end def can_rate?(user, dimension=nil) - rates.where(rater_id: user.id, dimension: dimension).size.zero? + rates(dimension).where(rater_id: user.id).blank? end def rates(dimension=nil) dimension ? self.send("#{dimension}_rates") : rates_without_dimension end - def raters(dimension=nil) + def raters_for(dimension=nil) dimension ? self.send("#{dimension}_raters") : raters_without_dimension end module ClassMethods - def ratyrate_rater - has_many :ratings_given, :class_name => "Rate", :foreign_key => :rater_id + has_many :ratings_given, class_name: "Rate", foreign_key: :rater_id end def ratyrate_rateable(*dimensions) - has_many :rates_without_dimension, -> { where dimension: nil}, :as => :rateable, :class_name => "Rate", :dependent => :destroy - has_many :raters_without_dimension, :through => :rates_without_dimension, :source => :rater + define_method :rating_dimensions do + dimensions + end + + has_many :rates_without_dimension, -> { where dimension: nil }, as: :rateable, class_name: "Rate" + has_many :raters_without_dimension, through: :rates_without_dimension, source: :rater + has_many :ratings, as: :rateable, class_name: 'Rate', dependent: :destroy + has_many :raters, -> { select("DISTINCT(rater_id)") }, through: :ratings, source: :rater + + has_one :rate_average_without_dimension, -> { where dimension: nil }, as: :cacheable, + class_name: "RatingCache", dependent: :destroy + has_many :average_rates_with_user, -> { where("rater_id IS NOT NULL") }, as: :rateable, class_name: 'RatingAverage', dependent: :destroy + has_one :average_rates, -> { where(rater_id: nil) }, as: :rateable, class_name: 'RatingAverage', dependent: :destroy - has_one :rate_average_without_dimension, -> { where dimension: nil}, :as => :cacheable, - :class_name => "RatingCache", :dependent => :destroy dimensions.each do |dimension| - has_many "#{dimension}_rates".to_sym, -> {where dimension: dimension.to_s}, - :dependent => :destroy, - :class_name => "Rate", - :as => :rateable + has_many "#{dimension}_rates".to_sym, -> { where dimension: dimension.to_s }, + dependent: :destroy, + class_name: "Rate", + as: :rateable - has_many "#{dimension}_raters".to_sym, :through => :"#{dimension}_rates", :source => :rater + has_many "#{dimension}_raters".to_sym, through: :"#{dimension}_rates", source: :rater has_one "#{dimension}_average".to_sym, -> { where dimension: dimension.to_s }, - :as => :cacheable, :class_name => "RatingCache", - :dependent => :destroy + as: :cacheable, class_name: "RatingCache", + dependent: :destroy end end end - end class ActiveRecord::Base diff --git a/vendor/assets/images/big-star.png b/vendor/assets/images/big-star.png new file mode 100644 index 0000000..9304638 Binary files /dev/null and b/vendor/assets/images/big-star.png differ diff --git a/lib/generators/ratyrate/templates/cancel-off.png b/vendor/assets/images/cancel-off.png similarity index 100% rename from lib/generators/ratyrate/templates/cancel-off.png rename to vendor/assets/images/cancel-off.png diff --git a/lib/generators/ratyrate/templates/cancel-on.png b/vendor/assets/images/cancel-on.png similarity index 100% rename from lib/generators/ratyrate/templates/cancel-on.png rename to vendor/assets/images/cancel-on.png diff --git a/lib/generators/ratyrate/templates/mid-star.png b/vendor/assets/images/mid-star.png similarity index 100% rename from lib/generators/ratyrate/templates/mid-star.png rename to vendor/assets/images/mid-star.png diff --git a/lib/generators/ratyrate/templates/star-half.png b/vendor/assets/images/star-half.png similarity index 100% rename from lib/generators/ratyrate/templates/star-half.png rename to vendor/assets/images/star-half.png diff --git a/lib/generators/ratyrate/templates/star-off.png b/vendor/assets/images/star-off.png similarity index 100% rename from lib/generators/ratyrate/templates/star-off.png rename to vendor/assets/images/star-off.png diff --git a/lib/generators/ratyrate/templates/star-on.png b/vendor/assets/images/star-on.png similarity index 100% rename from lib/generators/ratyrate/templates/star-on.png rename to vendor/assets/images/star-on.png diff --git a/lib/generators/ratyrate/templates/jquery.raty.js b/vendor/assets/javascripts/jquery.raty.js.erb similarity index 91% rename from lib/generators/ratyrate/templates/jquery.raty.js rename to vendor/assets/javascripts/jquery.raty.js.erb index 26f53bf..a42d2c0 100644 --- a/lib/generators/ratyrate/templates/jquery.raty.js +++ b/vendor/assets/javascripts/jquery.raty.js.erb @@ -38,7 +38,7 @@ self.opt.number = methods.between(self.opt.number, 0, 20) } - if (self.opt.path.substring(self.opt.path.length - 1, self.opt.path.length) != '/') { + if (self.opt.path.length > 0 && self.opt.path.substring(self.opt.path.length - 1, self.opt.path.length) != '/') { self.opt.path += '/'; } @@ -52,7 +52,7 @@ for (var i = 1; i <= self.opt.number; i++) { $('', { - src : self.opt.path + ((!self.opt.score || self.opt.score < i) ? self.opt.starOff : self.opt.starOn), + src : methods.starPath(self.opt.path, ((!self.opt.score || self.opt.score < i) ? self.opt.starOff : self.opt.starOn)), alt : i, title : (i <= self.opt.hints.length && self.opt.hints[i - 1] !== null) ? self.opt.hints[i - 1] : i }).appendTo(self); @@ -80,7 +80,7 @@ width = self.opt.width || (self.opt.number * self.opt.size + self.opt.number * space); if (self.opt.cancel) { - self.cancel = $('', { src: self.opt.path + self.opt.cancelOff, alt: 'x', title: self.opt.cancelHint, 'class': 'raty-cancel' }); + self.cancel = $('', { src: methods.starPath(self.opt.path, self.opt.cancelOff), alt: 'x', title: self.opt.cancelHint, 'class': 'raty-cancel' }); if (self.opt.cancelPlace == 'left') { $this.prepend(' ').prepend(self.cancel); @@ -105,7 +105,10 @@ $this.css('width', width); }); - }, between: function(value, min, max) { + }, starPath: function(path, starName){ + return path+starName; + } , + between: function(value, min, max) { return Math.min(Math.max(parseFloat(value), min), max); }, bindAction: function() { var self = this, @@ -126,9 +129,9 @@ if (self.opt.cancel) { self.cancel.mouseenter(function() { - $(this).attr('src', self.opt.path + self.opt.cancelOn); + $(this).attr('src', methods.starPath(self.opt.path, self.opt.cancelOn)); - self.stars.attr('src', self.opt.path + self.opt.starOff); + self.stars.attr('src', methods.starPath(self.opt.path, self.opt.starOff)); methods.setTarget.call(self, null, true); @@ -136,7 +139,7 @@ self.opt.mouseover.call(self, null); } }).mouseleave(function() { - $(this).attr('src', self.opt.path + self.opt.cancelOff); + $(this).attr('src', methods.starPath(self.opt.path, self.opt.cancelOff)); if (self.opt.mouseover) { self.opt.mouseover.call(self, self.score.val() || null); @@ -242,7 +245,7 @@ } if (i <= star.range) { - $star.attr('src', self.opt.path + icon); + $star.attr('src', methods.starPath(self.opt.path, icon)); } if (i == star.range) { @@ -255,7 +258,7 @@ icon = (i <= score) ? self.opt.starOn : self.opt.starOff; } - $star.attr('src', self.opt.path + icon); + $star.attr('src', methods.starPath(self.opt.path, icon)); } } }, fixHint: function() { @@ -325,7 +328,7 @@ icon = this.opt.starOff; } - this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + icon); + this.stars.eq(Math.ceil(score) - 1).attr('src', methods.starPath(this.opt.path, icon)); } // Full down: [x.00 .. x.25] }, score: function() { return arguments.length ? methods.setScore.apply(this, arguments) : methods.getScore.call(this); @@ -392,7 +395,7 @@ var diff = (score - Math.floor(score)).toFixed(1); if (diff > 0 && diff < .6) { - this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + this.opt.starHalf); + this.stars.eq(Math.ceil(score) - 1).attr('src', methods.starPath(this.opt.path, this.opt.starHalf)); } }, initialize: function(score) { score = !score ? 0 : methods.between(score, 0, this.opt.number); diff --git a/lib/generators/ratyrate/templates/ratyrate.js.erb b/vendor/assets/javascripts/ratyrate.js.erb similarity index 88% rename from lib/generators/ratyrate/templates/ratyrate.js.erb rename to vendor/assets/javascripts/ratyrate.js.erb index 40e7f2d..404e5f9 100644 --- a/lib/generators/ratyrate/templates/ratyrate.js.erb +++ b/vendor/assets/javascripts/ratyrate.js.erb @@ -1,6 +1,8 @@ +//= require 'jquery.raty' + $.fn.raty.defaults.half = false; $.fn.raty.defaults.halfShow = false; -$.fn.raty.defaults.path = "/assets"; +$.fn.raty.defaults.path = ""; $.fn.raty.defaults.cancel = false; function initstars(){ @@ -37,10 +39,12 @@ function initstars(){ targetType: $(this).attr('data-target-type'), targetFormat: $(this).attr('data-target-format'), targetScoret: $(this).attr('data-target-score'), + hints: JSON.parse($(this).attr('data-hints')), readOnly: $readonly, click: function(score, evt) { var _this = this; if (score == null) { score = 0; } + $(_this).trigger("rating:beforeUpdating", $(_this).target); $.post('<%= Rails.application.class.routes.url_helpers.rate_path %>', { score: score, @@ -49,12 +53,14 @@ function initstars(){ klass: $(this).attr('data-classname') }, function(data) { - if(data) { + if(data.success) { // success code goes here ... if ($(_this).attr('data-disable-after-rate') == 'true') { $(_this).raty('set', { readOnly: true, score: score }); + } + $(_this).trigger("rating:updated", data); } }); } @@ -63,4 +69,4 @@ function initstars(){ }; $(document).ready(initstars); -$(document).on('page:change',initstars); \ No newline at end of file +$(document).on('page:change',initstars);