Merge branch 'develop' of 10.0.47.245:/home/trustie2 into develop

This commit is contained in:
Wen 2014-04-23 09:22:34 +08:00
commit 59d705b33c
50 changed files with 309 additions and 382 deletions

View File

@ -6,7 +6,7 @@ unless RUBY_PLATFORM =~ /w32/
gem 'rubyzip'
gem 'zip-zip'
end
gem 'seems_rateable'
gem 'seems_rateable', path: 'lib/seems_rateable'
gem "rails", "3.2.13"
gem "jquery-rails", "~> 2.0.2"
gem "i18n", "~> 0.6.0"

View File

@ -1,15 +0,0 @@
require_dependency "seems_rateable/application_controller"
class RatingsController < ::ApplicationController
def create
raise NoCurrentUserInstanceError unless current_user
obj = params[:kls].classify.constantize.find(params[:idBox])
begin
obj.rate(params[:rate].to_i, current_user.id, params[:dimension])
render :json => true
rescue Errors::AlreadyRatedError
render :json => {:error => true}
end
end
end

View File

@ -16,7 +16,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
RedmineApp::Application.routes.draw do
resources :ratings, :only => :create
mount SeemsRateable::Engine => '/rateable', :as => :rateable
namespace :zipdown do
match 'assort'
end

View File

@ -1,21 +0,0 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
.project
.rvmrc
spec
test

View File

@ -1,32 +0,0 @@
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
require 'rdoc/task'
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'SeemsRateable'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
Bundler::GemHelper.install_tasks
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
require 'rspec/core'
require 'rspec/core/rake_task'
task :default => :spec

View File

@ -1,4 +0,0 @@
module SeemsRateable
class ApplicationController < ActionController::Base
end
end

View File

@ -1,4 +0,0 @@
module SeemsRateable
module ApplicationHelper
end
end

View File

@ -1,4 +0,0 @@
module SeemsRateable
module RatingsHelper
end
end

View File

@ -1,6 +0,0 @@
module SeemsRateable
class Rate < ActiveRecord::Base
belongs_to :rater, :class_name => SeemsRateable::Engine.config.owner_class
belongs_to :rateable, :polymorphic => true
end
end

View File

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>SeemsRateable</title>
<%= stylesheet_link_tag "seems_rateable/application", media: "all" %>
<%= javascript_include_tag "seems_rateable/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>

View File

@ -1,39 +0,0 @@
require 'rails/generators/migration'
require 'fileutils'
module SeemsRateable
module Generators
class InstallGenerator < ::Rails::Generators::Base
include Rails::Generators::Migration
source_root File.expand_path('../templates', __FILE__)
def self.next_migration_number(path)
unless @prev_migration_nr
@prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
else
@prev_migration_nr += 1
end
@prev_migration_nr.to_s
end
desc "generating migration files"
def copy_migrations
migration_template "rates_migration.rb", "db/migrate/create_seems_rateable_rates.rb"
migration_template "cached_ratings_migration.rb", "db/migrate/create_seems_rateable_cached_ratings.rb"
end
desc "generating initializer"
def copy_initializer
template "initializer.rb", "config/initializers/seems_rateable.rb"
end
desc "generating javascript files"
def copy_javascript_asset
Dir.mkdir "app/assets/javascripts/rateable" unless File.directory?("app/assets/javascripts/rateable")
copy_file "rateable.js.erb", "app/assets/javascripts/rateable/rateable.js.erb" unless File.exists?("app/assets/javascripts/rateable/rateable.js.erb")
copy_file "jRating.js.erb", "app/assets/javascripts/rateable/jRating.js.erb" unless File.exists?("app/assets/javascripts/rateable/jRating.js.erb")
end
end
end
end

View File

@ -1,17 +0,0 @@
class CreateSeemsRateableCachedRatings < ActiveRecord::Migration
def self.up
create_table :seems_rateable_cached_ratings do |t|
t.belongs_to :cacheable, :polymorphic => true
t.float :avg, :null => false
t.integer :cnt, :null => false
t.string :dimension
t.integer :cacheable_id, :limit => 8
t.string :cacheable_type
t.timestamps
end
end
def self.down
drop_table :cached_ratings
end
end

View File

@ -1,17 +0,0 @@
module SeemsRateable
class Engine < ::Rails::Engine
isolate_namespace SeemsRateable
config.generators do |g|
g.test_framework :rspec, :fixture => false
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
end
initializer :seems_rateable do
ActiveRecord::Base.send :include, SeemsRateable::Model
ActionView::Base.send :include, SeemsRateable::Helpers
ActionDispatch::Routing::Mapper.send :include, SeemsRateable::Routes
end
end
end

View File

@ -1,21 +0,0 @@
module SeemsRateable
module Errors
class InvalidRateableObjectError < StandardError
def to_s
"Stated object is not rateable. Add 'seems_rateable' to your object's class model."
end
end
class NoCurrentUserInstanceError < StandardError
def to_s
"User instance current_user is not available."
end
end
class AlreadyRatedError < StandardError
def to_s
"User has already rated an object."
end
end
end
end

View File

@ -1,27 +0,0 @@
module SeemsRateable
module Helpers
def rating_for(obj, opts={})
raise Errors::InvalidRateableObjectError unless obj.class.respond_to?(:rateable?)
options = {
:dimension => nil,
:static => false,
:class => 'rateable',
:id => nil
}.update(opts)
content_tag :div, "", "data-average" => obj.average(options[:dimension]) ? obj.average(options[:dimension]).avg : 0, :id => options[:id],
:class => "#{options[:class]}#{jdisabled?(options[:static])}",
"data-id" => obj.id, "data-kls" => obj.class.name, "data-dimension" => options[:dimension]
end
def seems_rateable_stylesheet
stylesheet_link_tag "seems_rateable/application", media: "all", "data-turbolinks-track" => true
end
private
def jdisabled?(option)
" jDisabled" if option || !current_user
end
end
end

View File

@ -1,111 +0,0 @@
require 'active_support/concern'
module SeemsRateable
module Model
extend ActiveSupport::Concern
def rate(stars, user_id, dimension=nil)
if !has_rated?(user_id, dimension)
self.rates.create do |r|
r.stars = stars
r.rater_id = user_id
end
update_overall_average_rating(stars, dimension)
elsif has_rated?(user_id, dimension) && can_update?
update_users_rating(stars, user_id, dimension)
else
raise Errors::AlreadyRatedError
end
end
def update_overall_average_rating(stars, dimension=nil)
if average(dimension).nil?
CachedRating.create do |r|
r.avg = stars
r.dimension = dimension
r.cacheable_id = self.id
r.cacheable_type = self.class.name
r.cnt = 1
end
else
r = average(dimension)
r.avg = (r.avg * r.cnt + stars) / (r.cnt+1)
r.cnt += 1
r.save!
end
end
def update_users_rating(stars, user_id, dimension=nil)
obj = rates(dimension).where(:rater_id => user_id).first
current_record = average(dimension)
current_record.avg = (current_record.avg*current_record.cnt - obj.stars + stars) / (current_record.cnt)
current_record.save!
obj.stars = stars
obj.save!
end
def average(dimension=nil)
if dimension.nil?
self.send "rate_average_without_dimension"
else
self.send "#{dimension}_average"
end
end
def rates(dimension=nil)
if dimension.nil?
self.send "rates_without_dimension"
else
self.send "#{dimension}_rates"
end
end
def raters(dimension=nil)
if dimension.nil?
self.send "raters_without_dimension"
else
self.send "#{dimension}_raters"
end
end
def has_rated?(user_id, dimension=nil)
record = self.rates(dimension).where(:rater_id => user_id)
record.empty? ? false : true
end
def can_update?
self.class.can_update?
end
module ClassMethods
def seems_rateable(opts={})
#has_many :rates_without_dimension, -> { where(dimension: nil) }, :as => :rateable, :class_name => SeemsRateable::Rate, :dependent => :destroy
has_many :rates_without_dimension, :conditions => { dimension: nil }, :as => :rateable, :class_name => SeemsRateable::Rate, :dependent => :destroy
has_many :raters_without_dimension, :through => :rates_without_dimension, :source => :rater
has_one :rate_average_without_dimension, :conditions => { dimension: nil }, :as => :cacheable, :class_name => SeemsRateable::CachedRating, :dependent => :destroy
@permission = opts[:allow_update] ? true : false
def self.can_update?
@permission
end
def self.rateable?
true
end
if opts[:dimensions].is_a?(Array)
opts[:dimensions].each do |dimension|
has_many :"#{dimension}_rates", :conditions => { dimension: dimension.to_s }, :dependent => :destroy, :class_name => SeemsRateable::Rate, :as => :rateable
has_many :"#{dimension}_raters", :through => :"#{dimension}_rates", :source => :rater
has_one :"#{dimension}_average", :conditions => { dimension: dimension.to_s }, :as => :cacheable, :class_name => SeemsRateable::CachedRating, :dependent => :destroy
end
end
end
def seems_rateable_rater
has_many :ratings_given, :class_name => SeemsRateable::Rate, :foreign_key => :rater_id
end
end
end
end

View File

@ -1,4 +0,0 @@
# desc "Explaining what the task does"
# task :seems_rateable do
# # Task goes here
# end

View File

@ -45,7 +45,7 @@ Don't forget to run
$ rake db:migrate
To prepare model add <code> seems_rateable </code> to your rateable model file. You can also pass a hash of options to
To prepare model add <code> seems_rateable </code> to your rateable model file. You can also pass a hash of options to
customize the functionality
<ul>
@ -76,7 +76,7 @@ And to object's raters e.g
@object.raters(:quantity)
To track user's given ratings add <code>seems_rateable_rater</code> to your rater model.
If your rater class is not "User"(e.g "Client" or "Customer") change configuration in initializer generated by this engine.
If your rater class is not "User"(e.g "Client" or "Customer") change configuration in initializer generated by this engine.
Now you can access user's ratings by <code>@user.ratings_given</code>
### Usage
@ -84,13 +84,13 @@ Now you can access user's ratings by <code>@user.ratings_given</code>
To display star rating use helper method <code>rating_for</code> in your view
#index.html.erb
rating_for @post
rating_for @post, :dimension => :quality, :class => 'post', :id => 'list'
rating_for @post, :static => true
You can specify these options :
<ul>
<li><code>:dimension</code>The dimension of the object</li>

View File

@ -0,0 +1,17 @@
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
require 'rdoc/task'
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'SeemsRateable'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.md')
rdoc.rdoc_files.include('lib/**/*.rb')
end
Bundler::GemHelper.install_tasks

View File

Before

Width:  |  Height:  |  Size: 1018 B

After

Width:  |  Height:  |  Size: 1018 B

View File

@ -20,43 +20,43 @@
.jRatingAverage {
background-color:#f62929;
position:relative;
top:0;
left:0;
z-index:2;
height:100%;
background-color:#f62929;
position:relative;
top:0;
left:0;
z-index:2;
height:100%;
}
.jRatingColor {
background-color:#FFD400; /* bgcolor of the stars*/
position:relative;
top:0;
left:0;
z-index:2;
height:100%;
background-color:#FFD400; /* bgcolor of the stars*/
position:relative;
top:0;
left:0;
z-index:2;
height:100%;
}
/** Div containing the stars **/
.jStar {
position:relative;
left:0;
z-index:3;
position:relative;
left:0;
z-index:3;
}
/** P containing the rate informations **/
p.jRatingInfos {
position: absolute;
z-index:9999;
background: transparent url('bg_jRatingInfos.png') no-repeat;
color: #CACACA;
display: none;
width: 91px;
height: 29px;
font-size:16px;
text-align:center;
padding-top:5px;
position: absolute;
z-index:9999;
background: transparent url('bg_jRatingInfos.png') no-repeat;
color: #CACACA;
display: none;
width: 91px;
height: 29px;
font-size:16px;
text-align:center;
padding-top:5px;
}
p.jRatingInfos span.maxRate {
color:#c9c9c9;
font-size:14px;
color:#c9c9c9;
font-size:14px;
}

View File

@ -0,0 +1,7 @@
module SeemsRateable
class ApplicationController < ::ApplicationController
rescue_from SeemsRateable::Errors::AlreadyRatedError do |exception|
render :json => {:error => true}
end
end
end

View File

@ -0,0 +1,16 @@
require_dependency "seems_rateable/application_controller"
module SeemsRateable
class RatingsController < ApplicationController
def create
raise Errors::NoCurrentUserInstanceError unless current_user
obj = params[:kls].classify.constantize.find(params[:idBox])
obj.rate(params[:rate].to_i, current_user.id, params[:dimension])
render :json => true
rescue Errors::NoCurrentUserInstanceError
render :json => {:error => 'you must be login.'}
end
end
end

View File

@ -1,5 +1,5 @@
module SeemsRateable
class CachedRating < ActiveRecord::Base
belongs_to :cacheable, :polymorphic => true
belongs_to :cacheable, :polymorphic => true
end
end

View File

@ -0,0 +1,6 @@
module SeemsRateable
class Rate < ActiveRecord::Base
belongs_to :rater, :class_name => SeemsRateable::Engine.config.owner_class
belongs_to :rateable, :polymorphic => true
end
end

View File

@ -0,0 +1,42 @@
require 'rails/generators/migration'
require 'fileutils'
module SeemsRateable
module Generators
class InstallGenerator < ::Rails::Generators::Base
include Rails::Generators::Migration
source_root File.expand_path('../templates', __FILE__)
def self.next_migration_number(path)
unless @prev_migration_nr
@prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
else
@prev_migration_nr += 1
end
@prev_migration_nr.to_s
end
def routegen
route("seems_rateable")
end
desc "generating migration files"
def copy_migrations
migration_template "rates_migration.rb", "db/migrate/create_seems_rateable_rates.rb"
migration_template "cached_ratings_migration.rb", "db/migrate/create_seems_rateable_cached_ratings.rb"
end
desc "generating initializer"
def copy_initializer
template "initializer.rb", "config/initializers/seems_rateable.rb"
end
desc "generating javascript files"
def copy_javascript_asset
Dir.mkdir "app/assets/javascripts/rateable" unless File.directory?("app/assets/javascripts/rateable")
copy_file "rateable.js.erb", "app/assets/javascripts/rateable/rateable.js.erb" unless File.exists?("app/assets/javascripts/rateable/rateable.js.erb")
copy_file "jRating.js.erb", "app/assets/javascripts/rateable/jRating.js.erb" unless File.exists?("app/assets/javascripts/rateable/jRating.js.erb")
end
end
end
end

View File

@ -0,0 +1,17 @@
class CreateSeemsRateableCachedRatings < ActiveRecord::Migration
def self.up
create_table :seems_rateable_cached_ratings do |t|
t.belongs_to :cacheable, :polymorphic => true
t.float :avg, :null => false
t.integer :cnt, :null => false
t.string :dimension
t.integer :cacheable_id, :limit => 8
t.string :cacheable_type
t.timestamps
end
end
def self.down
drop_table :cached_ratings
end
end

View File

@ -12,9 +12,9 @@
$.fn.jRating = function(op) {
var defaults = {
/** String vars **/
bigStarsPath : '<%= image_path "seems_rateable/stars.png" %>', // path of the icon stars.png
smallStarsPath : '<%= image_path "seems_rateable/small.png" %>', // path of the icon small.png
path : '<%= SeemsRateable::Engine.routes.url_helpers.ratings_path %>',
bigStarsPath : 'images/seems_rateable/stars.png', // path of the icon stars.png
smallStarsPath : 'images/seems_rateable/small.png', // path of the icon small.png
path : '/ratings',
type : 'big', // can be set to 'small' or 'big'
/** Boolean vars **/

View File

@ -11,7 +11,7 @@ $(document).ready(function(){
//showRateInfo:false, //Rate info panel, set true to display
//rateInfosX : 45, //In pixel - Absolute left position of the information box during mousemove.
//rateInfosY : 5, //In pixel - Absolute top position of the information box during mousemove.
path : '<%= SeemsRateable::Engine.routes.url_helpers.ratings_path %>',
path : '/ratings',
onSuccess : function(element, rate){
//something like ->
//alert('success');
@ -21,5 +21,5 @@ $(document).ready(function(){
$('<span class="text-error"><small style="display:inline-block;">You have already rated!</small></span>').insertAfter(element)
}
});
});

View File

@ -15,4 +15,4 @@ class CreateSeemsRateableRates < ActiveRecord::Migration
def self.down
drop_table :rates
end
end
end

View File

@ -1,8 +1,10 @@
begin
require 'rails'
require 'rails'
rescue LoadError
end
require "jquery-rails"
require "seems_rateable/engine"
require "seems_rateable/errors"
require "seems_rateable/helpers"

View File

@ -0,0 +1,16 @@
module SeemsRateable
class Engine < ::Rails::Engine
isolate_namespace SeemsRateable
config.generators do |g|
g.test_framework :rspec, :fixture => false
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
end
initializer :seems_rateable do
ActiveRecord::Base.send :include, SeemsRateable::Model
ActionView::Base.send :include, SeemsRateable::Helpers
ActionDispatch::Routing::Mapper.send :include, SeemsRateable::Routes
end
end
end

View File

@ -0,0 +1,21 @@
module SeemsRateable
module Errors
class InvalidRateableObjectError < StandardError
def to_s
"Stated object is not rateable. Add 'seems_rateable' to your object's class model."
end
end
class NoCurrentUserInstanceError < StandardError
def to_s
"User instance current_user is not available."
end
end
class AlreadyRatedError < StandardError
def to_s
"User has already rated an object."
end
end
end
end

View File

@ -0,0 +1,27 @@
module SeemsRateable
module Helpers
def rating_for(obj, opts={})
raise Errors::InvalidRateableObjectError unless obj.class.respond_to?(:rateable?)
options = {
:dimension => nil,
:static => false,
:class => 'rateable',
:id => nil
}.update(opts)
content_tag :div, "", "data-average" => obj.average(options[:dimension]) ? obj.average(options[:dimension]).avg : 0, :id => options[:id],
:class => "#{options[:class]}#{jdisabled?(options[:static])}",
"data-id" => obj.id, "data-kls" => obj.class.name, "data-dimension" => options[:dimension]
end
def seems_rateable_stylesheet
stylesheet_link_tag "seems_rateable/application", media: "all", "data-turbolinks-track" => true
end
private
def jdisabled?(option)
" jDisabled" if option || !current_user
end
end
end

View File

@ -0,0 +1,91 @@
require 'active_support/concern'
module SeemsRateable
module Model
extend ActiveSupport::Concern
def rate(stars, user_id, dimension=nil)
if !has_rated?(user_id, dimension)
self.rates.create do |r|
r.stars = stars
r.rater_id = user_id
r.dimension = dimension
end
update_overall_average_rating(stars, dimension)
elsif has_rated?(user_id, dimension) && can_update?
update_users_rating(stars, user_id, dimension)
else
raise Errors::AlreadyRatedError
end
end
def update_overall_average_rating(stars, dimension=nil)
r = average(dimension)
if r.nil?
self.rate_averages.create do |r|
r.avg = stars
r.dimension = dimension
r.cnt = 1
end
else
r.avg = (r.avg * r.cnt + stars) / (r.cnt+1)
r.cnt += 1
r.save!
r
end
end
def update_users_rating(stars, user_id, dimension=nil)
obj = rates(dimension).where(:rater_id => user_id).first
current_record = average(dimension)
current_record.avg = (current_record.avg*current_record.cnt - obj.stars + stars) / (current_record.cnt)
current_record.save!
obj.stars = stars
obj.save!
end
def average(dimension=nil)
rate_averages.where(dimension: dimension).first
end
def rates(dimension=nil)
rates_all.where(dimension: dimension)
end
def raters(dimension=nil)
raters_all.where('seems_rateable_rates.dimension = ?', dimension)
end
def has_rated?(user_id, dimension=nil)
record = self.rates(dimension).where(:rater_id => user_id)
record.empty? ? false : true
end
def can_update?
self.class.can_update?
end
module ClassMethods
def seems_rateable(opts={})
has_many :rates_all, :as => :rateable, :class_name => SeemsRateable::Rate, :dependent => :destroy
has_many :raters_all, :through => :rates_all, :class_name => SeemsRateable::Engine.config.owner_class, :source => :rater
has_many :rate_averages, :as => :cacheable, :class_name => SeemsRateable::CachedRating, :dependent => :destroy
self.class_variable_set(:@@permission, opts[:allow_update] ? true : false)
def self.can_update?
self.class_variable_get(:@@permission)
end
def self.rateable?
true
end
end
def seems_rateable_rater
has_many :ratings_given, :class_name => SeemsRateable::Rate, :foreign_key => :rater_id
end
end
end
end

View File

@ -1,3 +1,3 @@
module SeemsRateable
VERSION = "1.0.9"
VERSION = "1.0.13"
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -14,7 +14,7 @@
/** String vars **/
bigStarsPath : '/images/seems_rateable/stars.png', // path of the icon stars.png
smallStarsPath : '/images/seems_rateable/small.png', // path of the icon small.png
path : '/ratings',
path : '/rateable/ratings',
type : 'big', // can be set to 'small' or 'big'
/** Boolean vars **/

View File

@ -11,7 +11,7 @@ $(document).ready(function(){
//showRateInfo:false, //Rate info panel, set true to display
//rateInfosX : 45, //In pixel - Absolute left position of the information box during mousemove.
//rateInfosY : 5, //In pixel - Absolute top position of the information box during mousemove.
path : '/ratings',
path : '/rateable/ratings',
onSuccess : function(element, rate){
//something like ->
//alert('success');