favourite_object 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +23 -0
- data/Rakefile +12 -0
- data/app/assets/images/favourite_active.png +0 -0
- data/app/assets/images/favourite_default.png +0 -0
- data/app/assets/javascripts/favourite_object/favourites.js +33 -0
- data/app/assets/stylesheets/favourite_object_stylesheet.css +47 -0
- data/app/controllers/favourite_object/base_favourites_controller.rb +90 -0
- data/app/controllers/favourite_object/favourites_controller.rb +3 -0
- data/app/models/favourite_object/favourite.rb +73 -0
- data/app/serializer/favourite_object/favourite_serializer.rb +44 -0
- data/app/views/favourite_object/favourites/_favourite_icon.html.erb +25 -0
- data/app/views/favourite_object/favourites/index.html.erb +5 -0
- data/config/routes.rb +8 -0
- data/lib/favourite_object/engine.rb +11 -0
- data/lib/favourite_object/version.rb +3 -0
- data/lib/favourite_object.rb +18 -0
- data/lib/generators/favourite_object/install/USAGE +6 -0
- data/lib/generators/favourite_object/install/install_generator.rb +53 -0
- data/lib/generators/favourite_object/install/templates/create_favourite_object_favourites.rb +16 -0
- data/lib/generators/favourite_object/install/templates/initializer.rb +9 -0
- data/lib/generators/favourite_object/template/USAGE +6 -0
- data/lib/generators/favourite_object/template/template_generator.rb +16 -0
- data/lib/generators/favourite_object/template/templates/message.html.erb.erb +0 -0
- data/lib/tasks/favourite_tasks.rake +4 -0
- data/lib/tasks/test.rake +7 -0
- data/spec/controllers/favourite_object/favourites_controller_spec.rb +68 -0
- data/spec/dummy/rails-4.0.2/Gemfile +45 -0
- data/spec/dummy/rails-4.0.2/README.rdoc +28 -0
- data/spec/dummy/rails-4.0.2/Rakefile +6 -0
- data/spec/dummy/rails-4.0.2/app/assets/javascripts/application.js +22 -0
- data/spec/dummy/rails-4.0.2/app/assets/stylesheets/application.css +16 -0
- data/spec/dummy/rails-4.0.2/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/rails-4.0.2/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/rails-4.0.2/app/models/arbitrary_object.rb +2 -0
- data/spec/dummy/rails-4.0.2/app/models/user.rb +2 -0
- data/spec/dummy/rails-4.0.2/app/views/favourite_object/arbitrary_object/message.html.erb +0 -0
- data/spec/dummy/rails-4.0.2/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/rails-4.0.2/bin/bundle +3 -0
- data/spec/dummy/rails-4.0.2/bin/rails +4 -0
- data/spec/dummy/rails-4.0.2/bin/rake +4 -0
- data/spec/dummy/rails-4.0.2/config/application.rb +23 -0
- data/spec/dummy/rails-4.0.2/config/boot.rb +4 -0
- data/spec/dummy/rails-4.0.2/config/database.yml +25 -0
- data/spec/dummy/rails-4.0.2/config/environment.rb +5 -0
- data/spec/dummy/rails-4.0.2/config/environments/development.rb +29 -0
- data/spec/dummy/rails-4.0.2/config/environments/production.rb +80 -0
- data/spec/dummy/rails-4.0.2/config/environments/test.rb +36 -0
- data/spec/dummy/rails-4.0.2/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/rails-4.0.2/config/initializers/favourite_object.rb +9 -0
- data/spec/dummy/rails-4.0.2/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/rails-4.0.2/config/initializers/inflections.rb +16 -0
- data/spec/dummy/rails-4.0.2/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/rails-4.0.2/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/rails-4.0.2/config/initializers/session_store.rb +3 -0
- data/spec/dummy/rails-4.0.2/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/rails-4.0.2/config/locales/en.yml +23 -0
- data/spec/dummy/rails-4.0.2/config/routes.rb +56 -0
- data/spec/dummy/rails-4.0.2/config.ru +4 -0
- data/spec/dummy/rails-4.0.2/db/migrate/20140401014304_create_users.rb +9 -0
- data/spec/dummy/rails-4.0.2/db/migrate/20140401014305_create_arbitrary_objects.rb +9 -0
- data/spec/dummy/rails-4.0.2/db/migrate/20140401014306959_create_favourite_object_favourites.rb +16 -0
- data/spec/dummy/rails-4.0.2/db/schema.rb +42 -0
- data/spec/dummy/rails-4.0.2/db/seeds.rb +7 -0
- data/spec/dummy/rails-4.0.2/db/test.sqlite3 +0 -0
- data/spec/dummy/rails-4.0.2/log/test.log +935 -0
- data/spec/dummy/rails-4.0.2/public/404.html +58 -0
- data/spec/dummy/rails-4.0.2/public/422.html +58 -0
- data/spec/dummy/rails-4.0.2/public/500.html +57 -0
- data/spec/dummy/rails-4.0.2/public/favicon.ico +0 -0
- data/spec/dummy/rails-4.0.2/public/robots.txt +5 -0
- data/spec/dummy/rails-4.0.2/test/fixtures/arbitrary_objects.yml +7 -0
- data/spec/dummy/rails-4.0.2/test/fixtures/users.yml +7 -0
- data/spec/dummy/rails-4.0.2/test/models/arbitrary_object_test.rb +7 -0
- data/spec/dummy/rails-4.0.2/test/models/user_test.rb +7 -0
- data/spec/dummy/rails-4.0.2/test/test_helper.rb +15 -0
- data/spec/models/favourite_object/favourite_spec.rb +49 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/support/rails_template.rb +11 -0
- metadata +301 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: be831745b5092ec4f8c355d5e637656cb1d16def
|
4
|
+
data.tar.gz: 55696b4717f9caaee905b90062ebf8e01641f104
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 99499bd287e53784e804e0a9bcb70403f1d94da25c27375a270ed6e9fe5490aa716722b0267bf39fe756ba5f777acd237356cacada8d22cb855f4ac6284afdce
|
7
|
+
data.tar.gz: 3ae5df1b77729e04a95e1fc3d6410d78ab6b32d2fe52a019dc1bbecdcd3d1ee81f7e97c73d78bd5ba7c27015742e39c4cf0487025a59b1d93052c7c896b85517
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= Favourite Object
|
2
|
+
A dropin utility that adds favourites functionality to any rails application. But simpling include a partial you can add a favourite button to any object.
|
3
|
+
|
4
|
+
|
5
|
+
Install:
|
6
|
+
```
|
7
|
+
gem 'favourite_object'
|
8
|
+
rails g favourite_object:install
|
9
|
+
rake db:migrate
|
10
|
+
```
|
11
|
+
|
12
|
+
For every object you want to be favouritable
|
13
|
+
- Generates a favourite_object/#{name.underscore}/message.html.erb file which is used to display the description of an object
|
14
|
+
```
|
15
|
+
rails g favourite_object:template ObjectName
|
16
|
+
```
|
17
|
+
|
18
|
+
|
19
|
+
Favourite button(pass the object to be favourited and the user object)
|
20
|
+
```
|
21
|
+
<%= render :partial => 'favourite_object/favourites/favourite_icon',
|
22
|
+
:locals => {:object => object, :owner => @user}%>
|
23
|
+
```
|
data/Rakefile
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
$( document ).ready(function() {
|
2
|
+
$('.favourite_object_container .icon').click(function() {
|
3
|
+
element = $(this)
|
4
|
+
target_type = element.attr('-data-target-type');
|
5
|
+
target_id = element.attr('-data-target-id');
|
6
|
+
user_status = element.attr('-data-user-status');
|
7
|
+
third_party_flag = element.attr('-data-third-party');
|
8
|
+
params = element.attr('-data-params');
|
9
|
+
|
10
|
+
if(user_status == 'true'){
|
11
|
+
$.ajax({
|
12
|
+
type: "PUT",
|
13
|
+
url: '/favourite_object/favourites/'+ target_type +'/' + target_id + '/toggle' ,
|
14
|
+
data: {"target_type": target_type,
|
15
|
+
"target_id": target_id, "third_party_flag": third_party_flag, "params": params}
|
16
|
+
}).done(function(response){
|
17
|
+
if (response['favourite']['is_favourited'] == true){
|
18
|
+
element.addClass( "active" );
|
19
|
+
element.parent().parent().find('#favourited_text').addClass('active');
|
20
|
+
element.parent().parent().find('#unfavourited_text').removeClass('active');
|
21
|
+
}else{
|
22
|
+
element.removeClass( "active" );
|
23
|
+
element.parent().parent().find('#unfavourited_text').addClass('active');
|
24
|
+
element.parent().parent().find('#favourited_text').removeClass('active');
|
25
|
+
}
|
26
|
+
}).fail(function(){
|
27
|
+
console.log("failed");
|
28
|
+
});
|
29
|
+
}else{
|
30
|
+
alert("Please login to favourite");
|
31
|
+
}
|
32
|
+
});
|
33
|
+
});
|
@@ -0,0 +1,47 @@
|
|
1
|
+
.favourite_object_container{
|
2
|
+
display: inline-block;
|
3
|
+
}
|
4
|
+
|
5
|
+
.favourite_object_container .icon{
|
6
|
+
/*default state*/
|
7
|
+
background: url('favourite_default.png');
|
8
|
+
height: 24px;
|
9
|
+
width: 24px;
|
10
|
+
display: block;
|
11
|
+
cursor: pointer;
|
12
|
+
}
|
13
|
+
.favourite_object_container .icon_container{
|
14
|
+
display: inline-block;
|
15
|
+
}
|
16
|
+
.favourite_object_container .text_container{
|
17
|
+
display: inline-block;
|
18
|
+
vertical-align: top;
|
19
|
+
padding-top:3px;
|
20
|
+
margin-right: 3px;
|
21
|
+
}
|
22
|
+
.favourite_object_container #favourited_text, .favourite_object_container #unfavourited_text{
|
23
|
+
display: none;
|
24
|
+
}
|
25
|
+
.favourite_object_container .text_container .active{
|
26
|
+
display: inline !important;
|
27
|
+
}
|
28
|
+
.favourite_object_container .icon.active{
|
29
|
+
/*favourited state*/
|
30
|
+
background: url('favourite_active.png');
|
31
|
+
display: block;
|
32
|
+
}
|
33
|
+
|
34
|
+
.favourite_object_container .hide{
|
35
|
+
display:none;
|
36
|
+
}
|
37
|
+
.favourite_object_container .icon:before
|
38
|
+
{
|
39
|
+
position: relative;
|
40
|
+
left: -74px;
|
41
|
+
top: 3px;
|
42
|
+
/* content:"Favourite";
|
43
|
+
*/}
|
44
|
+
.favourite_object_container .icon.active:before
|
45
|
+
{
|
46
|
+
/* content:"Favourited";
|
47
|
+
*/}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class FavouriteObject::BaseFavouritesController < ApplicationController
|
2
|
+
|
3
|
+
before_filter :authenticate!
|
4
|
+
#remove before commiting
|
5
|
+
skip_before_filter :verify_authenticity_token
|
6
|
+
|
7
|
+
def index
|
8
|
+
#only return is_favourited = true
|
9
|
+
@favourites = FavouriteObject::Favourite.for_owner(@user)
|
10
|
+
.where(is_favourited: true)
|
11
|
+
.order("created_at DESC")
|
12
|
+
.page(params[:page]).per(params[:per_page])
|
13
|
+
|
14
|
+
@favourites = @favourites.with_type(params[:type]) if params[:type]
|
15
|
+
|
16
|
+
respond_to do |format|
|
17
|
+
format.html
|
18
|
+
format.json {render :json => @favourites, meta: { pagination: { per_page: @favourites.limit_value, total_pages: @favourites.total_pages, total_objects: @favourites.total_count } }}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def query
|
23
|
+
if params[:third_party_flag] == 'true' || params[:third_party_flag] == '1'
|
24
|
+
@favourite = FavouriteObject::Favourite.where(owner: @user, third_party_id: params[:target_id],
|
25
|
+
third_party_type: params[:target_type], third_party_flag: true).first_or_initialize
|
26
|
+
else
|
27
|
+
@favourite = FavouriteObject::Favourite.where(owner: @user, target_id: params[:target_id],
|
28
|
+
target_type: params[:target_type]).first_or_initialize
|
29
|
+
end
|
30
|
+
|
31
|
+
if @favourite.is_favourited == false
|
32
|
+
@favourite = {}
|
33
|
+
@favourite[:favourite] = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
render :json => @favourite, root: 'favourite'
|
37
|
+
end
|
38
|
+
|
39
|
+
def update
|
40
|
+
#endpoint for favouriting an object
|
41
|
+
if params[:third_party_flag] == 'true' || params[:third_party_flag] == '1'
|
42
|
+
favourite = FavouriteObject::Favourite.where(owner: @user, third_party_id: params[:target_id],
|
43
|
+
third_party_type: params[:target_type], third_party_flag: true).first_or_initialize
|
44
|
+
else
|
45
|
+
favourite = FavouriteObject::Favourite.where(owner: @user, target_id: params[:target_id],
|
46
|
+
target_type: params[:target_type]).first_or_initialize
|
47
|
+
end
|
48
|
+
|
49
|
+
# favourite.params = params[:data] if params[:data]
|
50
|
+
favourite.params = params[:data] if params[:data]
|
51
|
+
favourite.params[:description] = params[:description] if params[:description]
|
52
|
+
|
53
|
+
if params[:favourite] == 'true' || params[:favourite] == '1'
|
54
|
+
favourite.is_favourited = true
|
55
|
+
favourite.save
|
56
|
+
else
|
57
|
+
favourite.is_favourited = false
|
58
|
+
favourite.destroy
|
59
|
+
favourite = {}
|
60
|
+
favourite[:favourite] = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
render :json => favourite, root: 'favourite'
|
65
|
+
end
|
66
|
+
|
67
|
+
def toggle
|
68
|
+
# toggle for web interface
|
69
|
+
# DOES NOT ACCOUNT FOR THIRDPARTY FAVOURITES YET
|
70
|
+
if params[:third_party_flag] == 'true' || params[:third_party_flag] == '1'
|
71
|
+
favourite = FavouriteObject::Favourite.where(owner: @user, third_party_id: params[:target_id],
|
72
|
+
third_party_type: params[:target_type], third_party_flag: true).first_or_initialize
|
73
|
+
favourite.params = eval(params[:params]) if params[:params]
|
74
|
+
else
|
75
|
+
favourite = FavouriteObject::Favourite.where(owner: @user, target_id: params[:target_id],
|
76
|
+
target_type: params[:target_type]).first_or_initialize
|
77
|
+
end
|
78
|
+
favourite.toggle
|
79
|
+
|
80
|
+
render :json => favourite, root: 'favourite'
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def authenticate!
|
86
|
+
#fix before commiting
|
87
|
+
method(FavouriteObject.authentication_method).call
|
88
|
+
@user = method(FavouriteObject.current_user_method).call
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module FavouriteObject
|
2
|
+
class Favourite < ActiveRecord::Base
|
3
|
+
self.table_name = "favourite_object_favourites"
|
4
|
+
|
5
|
+
belongs_to :target, polymorphic: true
|
6
|
+
belongs_to :owner, polymorphic: true
|
7
|
+
|
8
|
+
# Params for creating the notification message.
|
9
|
+
serialize :params, Hash
|
10
|
+
|
11
|
+
mattr_accessor :views
|
12
|
+
@@views = {
|
13
|
+
message: {
|
14
|
+
template_path: Proc.new {|n| "favourite_object/#{n.target_type.underscore}/message" }
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
if ActiveRecord::VERSION::MAJOR < 4
|
19
|
+
attr_accessible :target, :owner
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.for_owner(owner)
|
23
|
+
where(owner_id: owner.id)
|
24
|
+
.where(owner_type: owner.class.base_class)
|
25
|
+
end
|
26
|
+
|
27
|
+
def message
|
28
|
+
ActionView::Base.new(
|
29
|
+
Rails.configuration.paths["app/views"]).render(
|
30
|
+
:template => self.class.views[:message][:template_path].call(self), :formats => [:html],
|
31
|
+
:locals => {object: self.target }, :layout => false)
|
32
|
+
end
|
33
|
+
|
34
|
+
#toggles the is_favourited status
|
35
|
+
def toggle
|
36
|
+
if is_favourited
|
37
|
+
self.is_favourited = false
|
38
|
+
else
|
39
|
+
self.is_favourited = true
|
40
|
+
end
|
41
|
+
self.save
|
42
|
+
end
|
43
|
+
|
44
|
+
def favourite
|
45
|
+
self.is_favourited = true
|
46
|
+
self.save
|
47
|
+
end
|
48
|
+
|
49
|
+
def un_favourite
|
50
|
+
self.is_favourited = false
|
51
|
+
self.save
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.is_favourited?(owner, target_id, target_type, third_party_flag=false)
|
55
|
+
if third_party_flag
|
56
|
+
favourite = FavouriteObject::Favourite.where(owner: owner, third_party_id: target_id.to_s,
|
57
|
+
third_party_type: target_type).first
|
58
|
+
else
|
59
|
+
favourite = FavouriteObject::Favourite.where(owner: owner, target_id: target_id,
|
60
|
+
target_type: target_type).first
|
61
|
+
end
|
62
|
+
|
63
|
+
return false if favourite.blank? || favourite.is_favourited == false
|
64
|
+
|
65
|
+
return true
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.with_type(type)
|
69
|
+
where('target_type = ?', type)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class FavouriteObject::FavouriteSerializer < ActiveModel::Serializer
|
2
|
+
root :favourites
|
3
|
+
|
4
|
+
attributes :id, :target_id, :target_type, :is_favourited, :description, :third_party_flag, :data
|
5
|
+
embed :ids, :include => true
|
6
|
+
has_one :target, polymorphic: true
|
7
|
+
|
8
|
+
def include_target?
|
9
|
+
(self.object.third_party_flag != true)
|
10
|
+
end
|
11
|
+
|
12
|
+
def description
|
13
|
+
if self.object.third_party_flag == true
|
14
|
+
self.object.params[:description]
|
15
|
+
else
|
16
|
+
self.object.message
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def data
|
21
|
+
if self.object.third_party_flag == true
|
22
|
+
self.object.params
|
23
|
+
else
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def target_id
|
29
|
+
if self.object.third_party_flag == true
|
30
|
+
self.object.third_party_id
|
31
|
+
else
|
32
|
+
self.object.target_id
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def target_type
|
37
|
+
if self.object.third_party_flag == true
|
38
|
+
self.object.third_party_type
|
39
|
+
else
|
40
|
+
self.object.target_type
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%
|
2
|
+
if defined?(third_party).nil?
|
3
|
+
third_party_flag = false
|
4
|
+
else
|
5
|
+
third_party_flag = third_party
|
6
|
+
end
|
7
|
+
user = method(FavouriteObject.current_user_method).call
|
8
|
+
status = FavouriteObject::Favourite.is_favourited?(user, object.id, object.class.name, third_party_flag) unless user.nil?
|
9
|
+
|
10
|
+
#defaults
|
11
|
+
@favourited_text = "Favourited" if defined?(favourited_text).nil?
|
12
|
+
@unfavourited_text = "Favourite" if defined?(unfavourited_text).nil?
|
13
|
+
%>
|
14
|
+
|
15
|
+
<div class="favourite_object_container">
|
16
|
+
<div class="text_container">
|
17
|
+
<span id="favourited_text" class=" <%= 'active' if status%>"><%= @favourited_text || favourited_text %></span>
|
18
|
+
<span id="unfavourited_text" class=" <%= 'active' unless status%>"><%= @unfavourited_text || unfavourited_text%></span>
|
19
|
+
</div>
|
20
|
+
<div class="icon_container">
|
21
|
+
<span class="icon <%= 'active' if status%>"
|
22
|
+
-data-target-type="<%= object.class %>" -data-params="<%= params %>" -data-target-id="<%= object.id %>" -data-third-party="<%= third_party_flag.to_s%>" -data-user-status="<%= user ? 'true' : 'false' %>"></span>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
namespace :favourite_object do
|
3
|
+
resources :favourites, only: [:index]
|
4
|
+
get 'favourites/:target_type/:target_id' => 'favourites#query'
|
5
|
+
put 'favourites/:target_type/:target_id' => 'favourites#update'
|
6
|
+
put 'favourites/:target_type/:target_id/toggle' => 'favourites#toggle'
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "favourite_object/engine"
|
2
|
+
require "kaminari"
|
3
|
+
require "active_model_serializers"
|
4
|
+
|
5
|
+
|
6
|
+
module FavouriteObject
|
7
|
+
|
8
|
+
mattr_accessor :authentication_method
|
9
|
+
@@authentication_method = nil
|
10
|
+
|
11
|
+
mattr_accessor :current_user_method
|
12
|
+
@@current_user_method = nil
|
13
|
+
|
14
|
+
# Used to set up FavouriteObject from the initializer.
|
15
|
+
def self.setup
|
16
|
+
yield self
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
class FavouriteObject::InstallGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def copy_migrations
|
9
|
+
copy_migration "create_favourite_object_favourites"
|
10
|
+
|
11
|
+
puts "Installation successful. You can now run:"
|
12
|
+
puts "rake db:migrate"
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_initializer
|
16
|
+
template "initializer.rb", "config/initializers/favourite_object.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
def append_stylesheet
|
20
|
+
insert_into_file "app/assets/stylesheets/application.css", :before => "*/" do
|
21
|
+
"\n *= require 'favourite_object/stylesheet'\n\n"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def append_javascript
|
26
|
+
insert_into_file "app/assets/javascripts/application.js", :after => %r{//= require +['"]?jquery['"]?} do
|
27
|
+
"\n//= require 'favourite_object/favourites'\n\n"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# This is defined in ActiveRecord::Generators::Base, but that inherits from NamedBase, so it expects a name argument
|
32
|
+
# which we don't want here. So we redefine it here. Yuck.
|
33
|
+
def self.next_migration_number(dirname)
|
34
|
+
if ActiveRecord::Base.timestamped_migrations
|
35
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S%L")
|
36
|
+
else
|
37
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def copy_migration(filename)
|
46
|
+
if self.class.migration_exists?("db/migrate", "#{filename}")
|
47
|
+
say_status("skipped", "Migration #{filename}.rb already exists")
|
48
|
+
else
|
49
|
+
migration_template "#{filename}.rb", "db/migrate/#{filename}.rb"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateFavouriteObjectFavourites < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :favourite_object_favourites do |t|
|
4
|
+
t.integer :target_id
|
5
|
+
t.string :target_type
|
6
|
+
t.string :third_party_id
|
7
|
+
t.string :third_party_type
|
8
|
+
t.integer :owner_id
|
9
|
+
t.string :owner_type
|
10
|
+
t.boolean :is_favourited, default: false
|
11
|
+
t.text :params
|
12
|
+
t.boolean :third_party_flag, default: false
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
FavouriteObject.setup do |config|
|
2
|
+
|
3
|
+
# NotifyUser will call this within NotificationsController to ensure the user is authenticated.
|
4
|
+
config.authentication_method = :authenticate_user!
|
5
|
+
|
6
|
+
# NotifyUser will call this within NotificationsController to return the current logged in user.
|
7
|
+
config.current_user_method = :current_user
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module FavouriteObject
|
2
|
+
class TemplateGenerator < Rails::Generators::NamedBase
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
argument :addition_classes, :type => :array, :default => []
|
5
|
+
|
6
|
+
def generate_templates
|
7
|
+
# generate template files for name
|
8
|
+
template "message.html.erb.erb", "app/views/favourite_object/#{name.underscore}/message.html.erb"
|
9
|
+
|
10
|
+
addition_classes.each do |class_name|
|
11
|
+
#iterates through each additional class and generates template files
|
12
|
+
template "message.html.erb.erb", "app/views/favourite_object/#{class_name.underscore}/message.html.erb"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
File without changes
|
data/lib/tasks/test.rake
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
desc "Creates a test rails app for the specs to run against"
|
2
|
+
task :setup do
|
3
|
+
system("mkdir spec/dummy") unless File.exists?("spec/dummy")
|
4
|
+
create_dummy = "bundle exec rails new #{ENV['RAILS_ROOT']} -m spec/support/rails_template.rb --skip-bundle"
|
5
|
+
puts "Running '#{create_dummy}'"
|
6
|
+
system(create_dummy)
|
7
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe FavouriteObject::FavouritesController do
|
5
|
+
|
6
|
+
let(:user) { User.create({email: "user@example.com" })}
|
7
|
+
let(:arbitrary_object) { ArbitraryObject.create() }
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
FavouriteObject::FavouritesController.any_instance.stub(:current_user).and_return(user)
|
11
|
+
FavouriteObject::FavouritesController.any_instance.stub(:authenticate_user!).and_return(true)
|
12
|
+
FavouriteObject::Favourite.any_instance.stub(:message).and_return("Mr. Blobby")
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "listing favourites" do
|
17
|
+
let(:favourite) { FavouriteObject::Favourite.create(owner: user, target: arbitrary_object) }
|
18
|
+
|
19
|
+
before :each do
|
20
|
+
favourite.is_favourited = true
|
21
|
+
favourite.save
|
22
|
+
end
|
23
|
+
|
24
|
+
it "displays favourites as json" do
|
25
|
+
get :index, format: :json
|
26
|
+
response.body.should have_json_path "favourites/0/id"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "displays favourites filtered by type" do
|
30
|
+
get :index, format: :json, type: "ArbitraryObject"
|
31
|
+
response.body.should have_json_path "favourites/0/id"
|
32
|
+
expect(json(response.body)["favourites"].length).to eq 1
|
33
|
+
end
|
34
|
+
|
35
|
+
it "displays favourites web template" do
|
36
|
+
get :index
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "unfavouriting an object" do
|
41
|
+
it "returns null if favourited is equal to false" do
|
42
|
+
put :update, target_type: arbitrary_object.class, target_id: arbitrary_object.id
|
43
|
+
expect(json(response.body)["favourite"]).to eq nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "if already exists exists and is_favourited is set to false the object gets deleted" do
|
47
|
+
favourite_object = FavouriteObject::Favourite.create(owner: user, target: arbitrary_object)
|
48
|
+
favourite_object.is_favourited = true
|
49
|
+
favourite_object.save
|
50
|
+
|
51
|
+
put :update, target_type: arbitrary_object.class.name, target_id: arbitrary_object.id, favourite: false
|
52
|
+
|
53
|
+
expect(json(response.body)["favourite"]).to eq nil
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "favourite a third_party object" do
|
59
|
+
it "assigns third_party values" do
|
60
|
+
put :update, target_type: "RandomClass", target_id: "object_1", third_party_flag: 'true', favourite: 'true'
|
61
|
+
|
62
|
+
favourite = FavouriteObject::Favourite.last
|
63
|
+
favourite.third_party_flag.should eq true
|
64
|
+
favourite.third_party_id.should eq "object_1"
|
65
|
+
favourite.third_party_type.should eq "RandomClass"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|