favourite_object 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|