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

@ -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');

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');