acts_as_favoritor 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/issue_template.md +14 -0
- data/.github/pull_request_template.md +21 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +1 -0
- data/DEPRECATIONS.md +3 -0
- data/Gemfile +3 -0
- data/README.md +86 -15
- data/Rakefile +0 -12
- data/acts_as_favoritor.gemspec +1 -0
- data/lib/acts_as_favoritor.rb +0 -23
- data/lib/acts_as_favoritor/favoritable.rb +190 -39
- data/lib/acts_as_favoritor/favorite_scopes.rb +13 -0
- data/lib/acts_as_favoritor/favoritor.rb +159 -34
- data/lib/acts_as_favoritor/favoritor_lib.rb +17 -3
- data/lib/acts_as_favoritor/version.rb +1 -1
- data/lib/generators/acts_as_favoritor_generator.rb +4 -0
- data/lib/generators/templates/README.md +1 -0
- data/lib/generators/templates/migration.rb.erb +2 -2
- data/lib/generators/templates/model.rb +0 -2
- data/test/acts_as_favoritable_test.rb +2 -2
- data/test/acts_as_favoritor_test.rb +12 -12
- data/test/dummy30/config/environments/development.rb +1 -0
- data/test/dummy30/config/environments/test.rb +1 -0
- data/test/favorite_test.rb +0 -18
- data/test/schema.rb +1 -1
- data/test/test_helper.rb +4 -0
- metadata +22 -5
- data/CHANGELOG.md +0 -15
- data/lib/generators/USAGE +0 -5
- data/test/README +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0212cb5d6caa611de18d2d40fdc63d222cb53fbd
|
4
|
+
data.tar.gz: 80a038d9ede85643ee8ef0f603e80ba6c5f4c621
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bd55853cbcfad24a096d22148f0ad9f8db4da64a8a9c8af89af0436c9debd0de3a24cfe6420fd07a96f9fd85f690c6d37b6dedc3762ad214712477e6f485bfc
|
7
|
+
data.tar.gz: d34d88eac6378f1a700409ee854a6e2f9c7257a700984cc63ee708fccf753eecdb57bb4a8812afbdacaabaa3b802fc8d3c5fd8f476a72f10a44e2c94fccc548a
|
@@ -0,0 +1,21 @@
|
|
1
|
+
### Summary
|
2
|
+
|
3
|
+
Provide a general description of the code changes in your pull
|
4
|
+
request... were there any bugs you had fixed? If so, mention them. If
|
5
|
+
these bugs have open GitHub issues, be sure to tag them here as well,
|
6
|
+
to keep the conversation linked together.
|
7
|
+
|
8
|
+
### Other Information
|
9
|
+
|
10
|
+
If there's anything else that's important and relevant to your pull
|
11
|
+
request, mention that information here. This could include
|
12
|
+
benchmarks, or other information.
|
13
|
+
|
14
|
+
If you are updating any of the CHANGELOG files or are asked to update the
|
15
|
+
CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.
|
16
|
+
|
17
|
+
Finally, if your pull request affects documentation or any non-code
|
18
|
+
changes, guidelines for those changes are [available
|
19
|
+
here](https://github.com/slooob/acts_as_favoritor/blob/master/CONTRIBUTING.md)
|
20
|
+
|
21
|
+
Thanks for contributing to `acts_as_favoritor`!
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6
|
+
|
7
|
+
## Our Standards
|
8
|
+
|
9
|
+
Examples of behavior that contributes to creating a positive environment include:
|
10
|
+
|
11
|
+
* Using welcoming and inclusive language
|
12
|
+
* Being respectful of differing viewpoints and experiences
|
13
|
+
* Gracefully accepting constructive criticism
|
14
|
+
* Focusing on what is best for the community
|
15
|
+
* Showing empathy towards other community members
|
16
|
+
|
17
|
+
Examples of unacceptable behavior by participants include:
|
18
|
+
|
19
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
20
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
21
|
+
* Public or private harassment
|
22
|
+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
23
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
24
|
+
|
25
|
+
## Our Responsibilities
|
26
|
+
|
27
|
+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
28
|
+
|
29
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
30
|
+
|
31
|
+
## Scope
|
32
|
+
|
33
|
+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
34
|
+
|
35
|
+
## Enforcement
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at help@slooob.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
38
|
+
|
39
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
40
|
+
|
41
|
+
## Attribution
|
42
|
+
|
43
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
44
|
+
|
45
|
+
[homepage]: http://contributor-covenant.org
|
46
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Contributing
|
data/DEPRECATIONS.md
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
<img src="https://travis-ci.org/slooob/acts_as_favoritor.svg?branch=master" />
|
4
4
|
|
5
|
-
`acts_as_favoritor` is a Rubygem to allow any ActiveRecord model to
|
5
|
+
`acts_as_favoritor` is a Rubygem to allow any ActiveRecord model to associate any other model including the option for multiple relationships per association with scopes.
|
6
|
+
|
7
|
+
You are able to differentiate followers, favorites, watchers and whatever else you can imagine through a single relationship. This is accomplished by a double polymorphic relationship on the Favorite model. There is also built in support for blocking/un-blocking favorite records.
|
6
8
|
|
7
9
|
---
|
8
10
|
|
@@ -14,8 +16,11 @@
|
|
14
16
|
* [`acts_as_favoritor` methods](#acts_as_favoritor-methods)
|
15
17
|
* [`acts_as_favoritable` methods](#acts_as_favoritable-methods)
|
16
18
|
* [`Favorite` model](#favorite-model)
|
17
|
-
* [
|
18
|
-
* [
|
19
|
+
* [Scopes](#scopes)
|
20
|
+
* [Testing](#testing)
|
21
|
+
* [Test Coverage](#test-coverage)
|
22
|
+
* [Contributing](#contributing)
|
23
|
+
* [Contributors](#contributors)
|
19
24
|
* [License](#license)
|
20
25
|
|
21
26
|
---
|
@@ -39,7 +44,7 @@ Or install it yourself as:
|
|
39
44
|
If you always want to be up to date fetch the latest from GitHub in your `Gemfile`:
|
40
45
|
|
41
46
|
```ruby
|
42
|
-
gem '
|
47
|
+
gem 'acts_as_favoritor', github: 'slooob/acts_as_favoritor'
|
43
48
|
```
|
44
49
|
|
45
50
|
Now run the generator:
|
@@ -92,15 +97,15 @@ user.remove_favorite book
|
|
92
97
|
user.favorited? book
|
93
98
|
|
94
99
|
# Total number of favorites by `user`.
|
95
|
-
user.
|
100
|
+
user.favorites_count
|
96
101
|
|
97
|
-
# Returnes `user`'s favorites that have not been blocked as an array of Favorite records.
|
102
|
+
# Returnes `user`'s favorites that have not been blocked as an array of `Favorite` records.
|
98
103
|
user.all_favorites
|
99
104
|
|
100
105
|
# Returns all favorited objects of `user` as an array (unblocked). This can be a collection of different object types, eg: `User`, `Book`.
|
101
106
|
user.all_favorited
|
102
107
|
|
103
|
-
# Returns an array of Favorite records where the `favoritable_type` is `Book`.
|
108
|
+
# Returns an array of `Favorite` records where the `favoritable_type` is `Book`.
|
104
109
|
user.favorites_by_type 'Book'
|
105
110
|
|
106
111
|
# Returns an array of all favorited objects of `user` where `favoritable_type` is 'Book', this can be a collection of different object types, eg: `User`, `Book`.
|
@@ -173,14 +178,14 @@ These methods take an optional hash parameter of ActiveRecord options (`:limit`,
|
|
173
178
|
|
174
179
|
```ruby
|
175
180
|
# Scopes
|
176
|
-
## Returns all Favorite records where `blocked` is `false`.
|
181
|
+
## Returns all `Favorite` records where `blocked` is `false`.
|
177
182
|
Favorite.unblocked
|
178
|
-
## Returns all Favorite records where `blocked` is `true`.
|
183
|
+
## Returns all `Favorite` records where `blocked` is `true`.
|
179
184
|
Favorite.blocked
|
180
|
-
## Returns an ordered array of the latest create Favorite records.
|
185
|
+
## Returns an ordered array of the latest create `Favorite` records.
|
181
186
|
Favorite.descending
|
182
187
|
|
183
|
-
# Returns all Favorite records in an array, which have been created in a specified timeframe. Default is 2 weeks.
|
188
|
+
# Returns all `Favorite` records in an array, which have been created in a specified timeframe. Default is 2 weeks.
|
184
189
|
Favorite.recent
|
185
190
|
Favorite.recent 1.month.ago
|
186
191
|
|
@@ -191,17 +196,83 @@ Favorite.for_favoritor user
|
|
191
196
|
Favorite.for_favoritable book
|
192
197
|
```
|
193
198
|
|
199
|
+
### Scopes
|
200
|
+
|
201
|
+
Using scopes with `acts_as_favoritor` enables you to Follow, Watch, Favorite, [...] between any of your models. This way you can separate distinct functionalities in your app between user states. For example: A user sees all his favorited books in a dashboard (`'favorites'`), but he only receives notifications for those, he is watching (`'watching'`). Just like YouTube does it.
|
202
|
+
|
203
|
+
By default all of your favorites are scoped to `'favorites'`.
|
204
|
+
|
205
|
+
You can create new scopes on the fly. Every single method takes `scope` as an option which expexts an array containing your scopes as strings.
|
206
|
+
|
207
|
+
So lets see how this works:
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
user.favorite book, scope: [:favorites, :watching]
|
211
|
+
user.remove_favorite book, scope: [:watching]
|
212
|
+
book.block user, scope: [:all] # applies to all scopes
|
213
|
+
```
|
214
|
+
|
215
|
+
That's simple!
|
216
|
+
|
217
|
+
When you call a method which returns something while specifying multiple scopes, the method returns the results in a hash with the scopes as keys:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
user.favorited? book, scope: [:favorites, :watching] # => { favorites: true, watching: false }
|
221
|
+
user.favorited? book, scope: [:all] # => true
|
222
|
+
```
|
223
|
+
|
224
|
+
`acts_as_favoritor` also provides some handy scopes for you to call on the `Favorite` model:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
# Returns all `Favorite` records where `scope` is `my_scope`
|
228
|
+
Favorite.send(my_scope + '_list')
|
229
|
+
|
230
|
+
## Examples
|
231
|
+
### Returns all `Favorite` records where `scope` is `favorites`
|
232
|
+
Favorite.favorites_list
|
233
|
+
### Returns all `Favorite` records where `scope` is `watching`
|
234
|
+
Favorite.watching_list
|
235
|
+
### Very unnecessary, but `all_list` returns literally all `Favorite` records
|
236
|
+
Favorite.all_list
|
237
|
+
```
|
238
|
+
|
194
239
|
---
|
195
240
|
|
196
|
-
##
|
241
|
+
## Testing
|
242
|
+
|
243
|
+
Tests are written with Shoulda on top of `Test::Unit` with Factory Girl being used instead of fixtures. Tests are run using rake.
|
244
|
+
|
245
|
+
1. Fork this repository
|
246
|
+
2. Clone your forked git locally
|
247
|
+
3. Install dependencies
|
248
|
+
|
249
|
+
`$ bundle install`
|
250
|
+
|
251
|
+
4. Run tests
|
197
252
|
|
198
|
-
|
253
|
+
`$ rake test`
|
254
|
+
|
255
|
+
### Test Coverage
|
256
|
+
|
257
|
+
Test coverage can be calculated using SimpleCov. Make sure you have the [simplecov gem](https://github.com/colszowka/simplecov) installed.
|
258
|
+
|
259
|
+
1. Uncomment SimpleCov in the Gemfile
|
260
|
+
2. Uncomment the relevant section in `test/test_helper.rb`
|
261
|
+
3. Run tests
|
262
|
+
|
263
|
+
`$ rake test`
|
199
264
|
|
200
265
|
---
|
201
266
|
|
202
|
-
##
|
267
|
+
## Contributing
|
268
|
+
|
269
|
+
We hope that you will consider contributing to `acts_as_favoritor`. Please read this short overview for some information about how to get started:
|
270
|
+
|
271
|
+
[Learn more about contributing to this repository](https://github.com/slooob/acts_as_favoritor/blob/master/CONTRIBUTING.md), [Code of Conduct](https://github.com/slooob/acts_as_favoritor/blob/master/CODE_OF_CONDUCT.md)
|
272
|
+
|
273
|
+
### Contributors
|
203
274
|
|
204
|
-
Give the people some :heart: who are working on this project.
|
275
|
+
Give the people some :heart: who are working on this project. See them all at:
|
205
276
|
|
206
277
|
https://github.com/slooob/acts_as_favoritor/graphs/contributors
|
207
278
|
|
data/Rakefile
CHANGED
@@ -23,15 +23,3 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
23
23
|
rdoc.options << '--line-numbers' << '--inline-source'
|
24
24
|
rdoc.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
|
25
25
|
end
|
26
|
-
|
27
|
-
namespace :rcov do
|
28
|
-
desc "Generate a coverage report in coverage/"
|
29
|
-
task :gen do
|
30
|
-
sh "rcov --output coverage test/*_test.rb --exclude 'gems/*'"
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "Remove generated coverage files."
|
34
|
-
task :clobber do
|
35
|
-
sh "rm -rdf coverage"
|
36
|
-
end
|
37
|
-
end
|
data/acts_as_favoritor.gemspec
CHANGED
data/lib/acts_as_favoritor.rb
CHANGED
@@ -7,29 +7,6 @@ module ActsAsFavoritor
|
|
7
7
|
autoload :FavoritorLib, 'acts_as_favoritor/favoritor_lib'
|
8
8
|
autoload :FavoriteScopes, 'acts_as_favoritor/favorite_scopes'
|
9
9
|
|
10
|
-
def self.setup
|
11
|
-
@configuration ||= Configuration.new
|
12
|
-
yield @configuration if block_given?
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.method_missing method_name, *args, &block
|
16
|
-
if method_name == :custom_parent_classes=
|
17
|
-
ActiveSupport::Deprecation.warn 'Setting custom parent classes is deprecated and will be removed in future versions.'
|
18
|
-
end
|
19
|
-
@configuration.respond_to?(method_name) ?
|
20
|
-
@configuration.send(method_name, *args, &block) : super
|
21
|
-
end
|
22
|
-
|
23
|
-
class Configuration
|
24
|
-
attr_accessor :custom_parent_classes
|
25
|
-
|
26
|
-
def initialize
|
27
|
-
@custom_parent_classes = []
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
setup
|
32
|
-
|
33
10
|
require 'acts_as_favoritor/railtie' if defined?(Rails)
|
34
11
|
|
35
12
|
end
|
@@ -16,30 +16,71 @@ module ActsAsFavoritor #:nodoc:
|
|
16
16
|
module InstanceMethods
|
17
17
|
|
18
18
|
# Returns the number of favoritors a record has.
|
19
|
-
def favoritors_count
|
20
|
-
|
19
|
+
def favoritors_count options = {}
|
20
|
+
if options.has_key?(:multiple_scopes) == false
|
21
|
+
validate_scopes __method__, options
|
22
|
+
elsif options[:multiple_scopes] == true
|
23
|
+
results = {}
|
24
|
+
options[:scope].each do |scope|
|
25
|
+
results[scope] = favorited.unblocked.send(scope + '_list').count
|
26
|
+
end
|
27
|
+
return results
|
28
|
+
else
|
29
|
+
return favorited.unblocked.send(options[:scope] + '_list').count
|
30
|
+
end
|
21
31
|
end
|
22
32
|
|
23
33
|
# Returns the favoritors by a given type
|
24
34
|
def favoritors_by_type favoritor_type, options = {}
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
if options.has_key?(:multiple_scopes) == false
|
36
|
+
options[:parameter] = favoritor_type
|
37
|
+
validate_scopes __method__, options
|
38
|
+
elsif options[:multiple_scopes] == true
|
39
|
+
results = {}
|
40
|
+
options[:scope].each do |scope|
|
41
|
+
favorites = favoritor_type.constantize.joins(:favorites).where('favorites.blocked': false,
|
42
|
+
'favorites.favoritable_id': id,
|
43
|
+
'favorites.favoritable_type': parent_class_name(self),
|
44
|
+
'favorites.favoritor_type': favoritor_type,
|
45
|
+
'favorites.scope': scope)
|
46
|
+
if options.has_key? :limit
|
47
|
+
favorites = favorites.limit options[:limit]
|
48
|
+
end
|
49
|
+
if options.has_key? :includes
|
50
|
+
favorites = favorites.includes options[:includes]
|
51
|
+
end
|
52
|
+
results[scope] = favorites
|
53
|
+
end
|
54
|
+
return results
|
55
|
+
else
|
56
|
+
favorites = favoritor_type.constantize.joins(:favorites).where('favorites.blocked': false,
|
57
|
+
'favorites.favoritable_id': id,
|
58
|
+
'favorites.favoritable_type': parent_class_name(self),
|
59
|
+
'favorites.favoritor_type': favoritor_type,
|
60
|
+
'favorites.scope': options[:scope])
|
61
|
+
if options.has_key? :limit
|
62
|
+
favorites = favorites.limit options[:limit]
|
63
|
+
end
|
64
|
+
if options.has_key? :includes
|
65
|
+
favorites = favorites.includes options[:includes]
|
66
|
+
end
|
67
|
+
return favorites
|
36
68
|
end
|
37
|
-
|
38
|
-
favorites
|
39
69
|
end
|
40
70
|
|
41
|
-
def favoritors_by_type_count favoritor_type
|
42
|
-
|
71
|
+
def favoritors_by_type_count favoritor_type, options = {}
|
72
|
+
if options.has_key?(:multiple_scopes) == false
|
73
|
+
options[:parameter] = favoritor_type
|
74
|
+
validate_scopes __method__, options
|
75
|
+
elsif options[:multiple_scopes] == true
|
76
|
+
results = {}
|
77
|
+
options[:scope].each do |scope|
|
78
|
+
results[scope] = favorited.unblocked.send(scope + '_list').for_favoritor_type(favoritor_type).count
|
79
|
+
end
|
80
|
+
return results
|
81
|
+
else
|
82
|
+
return favorited.unblocked.send(options[:scope] + '_list').for_favoritor_type(favoritor_type).count
|
83
|
+
end
|
43
84
|
end
|
44
85
|
|
45
86
|
# Allows magic names on favoritors_by_type
|
@@ -60,53 +101,163 @@ module ActsAsFavoritor #:nodoc:
|
|
60
101
|
super || m.to_s[/count_(.+)_favoritors/] || m.to_s[/(.+)_favoritors/]
|
61
102
|
end
|
62
103
|
|
63
|
-
def blocked_favoritors_count
|
64
|
-
|
104
|
+
def blocked_favoritors_count options = {}
|
105
|
+
if options.has_key?(:multiple_scopes) == false
|
106
|
+
validate_scopes __method__, options
|
107
|
+
elsif options[:multiple_scopes] == true
|
108
|
+
results = {}
|
109
|
+
options[:scope].each do |scope|
|
110
|
+
results[scope] = favorited.blocked.send(scope + '_list').count
|
111
|
+
end
|
112
|
+
return results
|
113
|
+
else
|
114
|
+
return favorited.blocked.send(options[:scope] + '_list').count
|
115
|
+
end
|
65
116
|
end
|
66
117
|
|
67
118
|
# Returns the favorited records scoped
|
68
|
-
def favoritors_scoped
|
69
|
-
|
119
|
+
def favoritors_scoped options = {}
|
120
|
+
if options.has_key?(:multiple_scopes) == false
|
121
|
+
validate_scopes __method__, options
|
122
|
+
elsif options[:multiple_scopes] == true
|
123
|
+
results = {}
|
124
|
+
options[:scope].each do |scope|
|
125
|
+
results[scope] = favorited.send(scope + '_list').includes :favoritor
|
126
|
+
end
|
127
|
+
return results
|
128
|
+
else
|
129
|
+
return favorited.send(options[:scope] + '_list').includes :favoritor
|
130
|
+
end
|
70
131
|
end
|
71
132
|
|
72
133
|
def favoritors options = {}
|
73
|
-
|
74
|
-
|
75
|
-
|
134
|
+
if options.has_key?(:multiple_scopes) == false
|
135
|
+
validate_scopes __method__, options
|
136
|
+
elsif options[:multiple_scopes] == true
|
137
|
+
results = {}
|
138
|
+
options[:scope].each do |scope|
|
139
|
+
favoritors_scope = favoritors_scoped(scope).unblocked
|
140
|
+
favoritors_scope = apply_options_to_scope favoritors_scope, options
|
141
|
+
results[scope] = favoritors_scope.to_a.collect{ |f| f.favoritor }
|
142
|
+
end
|
143
|
+
return results
|
144
|
+
else
|
145
|
+
favoritors_scope = favoritors_scoped(options[:scope]).unblocked
|
146
|
+
favoritors_scope = apply_options_to_scope favoritors_scope, options
|
147
|
+
return favoritors_scope.to_a.collect{ |f| f.favoritor }
|
148
|
+
end
|
76
149
|
end
|
77
150
|
|
78
151
|
def blocks options = {}
|
79
|
-
|
80
|
-
|
81
|
-
|
152
|
+
if options.has_key?(:multiple_scopes) == false
|
153
|
+
validate_scopes __method__, options
|
154
|
+
elsif options[:multiple_scopes] == true
|
155
|
+
results = {}
|
156
|
+
options[:scope].each do |scope|
|
157
|
+
blocked_favoritors_scope = favoritors_scoped(scope).blocked
|
158
|
+
blocked_favoritors_scope = apply_options_to_scope blocked_favoritors_scope, options
|
159
|
+
results[scope] = blocked_favoritors_scope.to_a.collect{ |f| f.favoritor }
|
160
|
+
end
|
161
|
+
return results
|
162
|
+
else
|
163
|
+
blocked_favoritors_scope = favoritors_scoped(options[:scope]).blocked
|
164
|
+
blocked_favoritors_scope = apply_options_to_scope blocked_favoritors_scope, options
|
165
|
+
return blocked_favoritors_scope.to_a.collect{ |f| f.favoritor }
|
166
|
+
end
|
82
167
|
end
|
83
168
|
|
84
169
|
# Returns true if the current instance is favorited by the passed record
|
85
170
|
# Returns false if the current instance is blocked by the passed record or no favorite is found
|
86
|
-
def favorited_by? favoritor
|
87
|
-
|
171
|
+
def favorited_by? favoritor, options = {}
|
172
|
+
if options.has_key?(:multiple_scopes) == false
|
173
|
+
options[:parameter] = favoritor
|
174
|
+
validate_scopes __method__, options
|
175
|
+
elsif options[:multiple_scopes] == true
|
176
|
+
results = {}
|
177
|
+
options[:scope].each do |scope|
|
178
|
+
results[scope] = favorited.unblocked.send(scope + '_list').for_favoritor(favoritor).first.present?
|
179
|
+
end
|
180
|
+
return results
|
181
|
+
else
|
182
|
+
return favorited.unblocked.send(options[:scope] + '_list').for_favoritor(favoritor).first.present?
|
183
|
+
end
|
88
184
|
end
|
89
185
|
|
90
|
-
def block favoritor
|
91
|
-
|
186
|
+
def block favoritor, options = {}
|
187
|
+
if options.has_key?(:multiple_scopes) == false
|
188
|
+
options[:parameter] = favoritor
|
189
|
+
validate_scopes __method__, options
|
190
|
+
elsif options[:multiple_scopes] == true
|
191
|
+
results = {}
|
192
|
+
options[:scope].each do |scope|
|
193
|
+
results[scope] = get_favorite_for(favoritor, scope: scope) ? block_existing_favorite(favoritor, scope: scope) : block_future_favorite(favoritor, scope: scope)
|
194
|
+
end
|
195
|
+
return results
|
196
|
+
else
|
197
|
+
return get_favorite_for(favoritor, scope: options[:scope]) ? block_existing_favorite(favoritor, scope: options[:scope]) : block_future_favorite(favoritor, scope: options[:scope])
|
198
|
+
end
|
92
199
|
end
|
93
200
|
|
94
|
-
def unblock favoritor
|
95
|
-
|
201
|
+
def unblock favoritor, options = {}
|
202
|
+
if options.has_key?(:multiple_scopes) == false
|
203
|
+
options[:parameter] = favoritor
|
204
|
+
validate_scopes __method__, options
|
205
|
+
elsif options[:multiple_scopes] == true
|
206
|
+
results = {}
|
207
|
+
options[:scope].each do |scope|
|
208
|
+
results[scope] = get_favorite_for(favoritor, scope: scope).update_attribute :blocked, false
|
209
|
+
end
|
210
|
+
return results
|
211
|
+
else
|
212
|
+
return get_favorite_for(favoritor, scope: options[:scope]).update_attribute :blocked, false
|
213
|
+
end
|
96
214
|
end
|
97
215
|
|
98
|
-
def get_favorite_for favoritor
|
99
|
-
|
216
|
+
def get_favorite_for favoritor, options = {}
|
217
|
+
if options.has_key?(:multiple_scopes) == false
|
218
|
+
options[:parameter] = favoritor
|
219
|
+
validate_scopes __method__, options
|
220
|
+
elsif options[:multiple_scopes] == true
|
221
|
+
results = {}
|
222
|
+
options[:scope].each do |scope|
|
223
|
+
results[scope] = favorited.send(scope + '_list').for_favoritor(favoritor).first
|
224
|
+
end
|
225
|
+
return results
|
226
|
+
else
|
227
|
+
return favorited.send(options[:scope] + '_list').for_favoritor(favoritor).first
|
228
|
+
end
|
100
229
|
end
|
101
230
|
|
102
231
|
private
|
103
232
|
|
104
|
-
def block_future_favorite favoritor
|
105
|
-
|
233
|
+
def block_future_favorite favoritor, options = {}
|
234
|
+
if options.has_key?(:multiple_scopes) == false
|
235
|
+
options[:parameter] = favoritor
|
236
|
+
validate_scopes __method__, options
|
237
|
+
elsif options[:multiple_scopes] == true
|
238
|
+
results = {}
|
239
|
+
options[:scope].each do |scope|
|
240
|
+
results[scope] = Favorite.create favoritable: self, favoritor: favoritor, blocked: true, scope: scope
|
241
|
+
end
|
242
|
+
return results
|
243
|
+
else
|
244
|
+
return Favorite.create favoritable: self, favoritor: favoritor, blocked: true, scope: options[:scope]
|
245
|
+
end
|
106
246
|
end
|
107
247
|
|
108
|
-
def block_existing_favorite favoritor
|
109
|
-
|
248
|
+
def block_existing_favorite favoritor, options = {}
|
249
|
+
if options.has_key?(:multiple_scopes) == false
|
250
|
+
options[:parameter] = favoritor
|
251
|
+
validate_scopes __method__, options
|
252
|
+
elsif options[:multiple_scopes] == true
|
253
|
+
results = {}
|
254
|
+
options[:scope].each do |scope|
|
255
|
+
results[scope] = get_favorite_for(favoritor, scope: scope).block!
|
256
|
+
end
|
257
|
+
return results
|
258
|
+
else
|
259
|
+
return get_favorite_for(favoritor, scope: options[:scope]).block!
|
260
|
+
end
|
110
261
|
end
|
111
262
|
|
112
263
|
end
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module ActsAsFavoritor #:nodoc:
|
2
2
|
module FavoriteScopes
|
3
3
|
|
4
|
+
# send(scope + '_list') - returns favorite records of scope
|
5
|
+
Favorite.all.group_by(&:scope).each do |s|
|
6
|
+
Favorite.send(:define_method, "#{s}_list") do
|
7
|
+
where scope: s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
def favorites_list
|
11
|
+
where scope: 'favorites'
|
12
|
+
end
|
13
|
+
def all_list
|
14
|
+
all
|
15
|
+
end
|
16
|
+
|
4
17
|
# returns favorite records where favoritor is the record passed in.
|
5
18
|
def for_favoritor favoritor
|
6
19
|
where favoritor_id: favoritor.id, favoritor_type: parent_class_name(favoritor)
|
@@ -16,72 +16,186 @@ module ActsAsFavoritor #:nodoc:
|
|
16
16
|
module InstanceMethods
|
17
17
|
|
18
18
|
# Returns true if this instance has favorited the object passed as an argument.
|
19
|
-
def favorited? favoritable
|
20
|
-
|
19
|
+
def favorited? favoritable, options = {}
|
20
|
+
if options.has_key?(:multiple_scopes) == false
|
21
|
+
options[:parameter] = favoritable
|
22
|
+
validate_scopes __method__, options
|
23
|
+
elsif options[:multiple_scopes] == true
|
24
|
+
results = {}
|
25
|
+
options[:scope].each do |scope|
|
26
|
+
results[scope] = 0 < Favorite.unblocked.send(scope + '_list').for_favoritor(self).for_favoritable(favoritable).count
|
27
|
+
end
|
28
|
+
return results
|
29
|
+
else
|
30
|
+
return 0 < Favorite.unblocked.send(options[:scope] + '_list').for_favoritor(self).for_favoritable(favoritable).count
|
31
|
+
end
|
21
32
|
end
|
22
33
|
|
23
34
|
# Returns the number of objects this instance has favorited.
|
24
|
-
def favorites_count
|
25
|
-
|
35
|
+
def favorites_count options = {}
|
36
|
+
if options.has_key?(:multiple_scopes) == false
|
37
|
+
validate_scopes __method__, options
|
38
|
+
elsif options[:multiple_scopes] == true
|
39
|
+
raise options.to_s
|
40
|
+
results = {}
|
41
|
+
options[:scope].each do |scope|
|
42
|
+
results[scope] = Favorite.unblocked.send(scope + '_list').for_favoritor(self).count
|
43
|
+
end
|
44
|
+
return results
|
45
|
+
else
|
46
|
+
return Favorite.unblocked.send(options[:scope] + '_list').for_favoritor(self).count
|
47
|
+
end
|
26
48
|
end
|
27
49
|
|
28
50
|
# Creates a new favorite record for this instance to favorite the passed object.
|
29
51
|
# Does not allow duplicate records to be created.
|
30
|
-
def favorite favoritable
|
31
|
-
if
|
32
|
-
|
33
|
-
|
52
|
+
def favorite favoritable, options = {}
|
53
|
+
if options.has_key?(:multiple_scopes) == false
|
54
|
+
options[:parameter] = favoritable
|
55
|
+
validate_scopes __method__, options
|
56
|
+
elsif options[:multiple_scopes] == true
|
57
|
+
results = {}
|
58
|
+
options[:scope].each do |scope|
|
59
|
+
if self != favoritable && scope != 'all'
|
60
|
+
params = {favoritable_id: favoritable.id, favoritable_type: parent_class_name(favoritable), scope: scope}
|
61
|
+
results[scope] = favorites.where(params).first_or_create!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
return results
|
65
|
+
else
|
66
|
+
if self != favoritable && options[:scope] != 'all'
|
67
|
+
params = {favoritable_id: favoritable.id, favoritable_type: parent_class_name(favoritable), scope: options[:scope]}
|
68
|
+
return favorites.where(params).first_or_create!
|
69
|
+
end
|
34
70
|
end
|
35
71
|
end
|
36
72
|
|
37
73
|
# Deletes the favorite record if it exists.
|
38
|
-
def remove_favorite favoritable
|
39
|
-
if
|
40
|
-
|
74
|
+
def remove_favorite favoritable, options = {}
|
75
|
+
if options.has_key?(:multiple_scopes) == false
|
76
|
+
options[:parameter] = favoritable
|
77
|
+
validate_scopes __method__, options
|
78
|
+
elsif options[:multiple_scopes] == true
|
79
|
+
results = {}
|
80
|
+
options[:scope].each do |scope|
|
81
|
+
if favorite = get_favorite(favoritable).send(scope + '_list')
|
82
|
+
results[scope] = favorite.destroy
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return results
|
86
|
+
else
|
87
|
+
if favorite = get_favorite(favoritable).send(options[:scope] + '_list')
|
88
|
+
return favorite.destroy
|
89
|
+
end
|
41
90
|
end
|
42
91
|
end
|
43
92
|
|
44
93
|
# returns the favorite records to the current instance
|
45
|
-
def favorites_scoped
|
46
|
-
|
94
|
+
def favorites_scoped options = {}
|
95
|
+
if options.has_key?(:multiple_scopes) == false
|
96
|
+
validate_scopes __method__, options
|
97
|
+
elsif options[:multiple_scopes] == true
|
98
|
+
results = {}
|
99
|
+
options[:scope].each do |scope|
|
100
|
+
results[scope] = favorites.unblocked.send(scope + '_list').includes :favoritable
|
101
|
+
end
|
102
|
+
return results
|
103
|
+
else
|
104
|
+
return favorites.unblocked.send(options[:scope] + '_list').includes :favoritable
|
105
|
+
end
|
47
106
|
end
|
48
107
|
|
49
108
|
# Returns the favorite records related to this instance by type.
|
50
109
|
def favorites_by_type favoritable_type, options = {}
|
51
|
-
|
52
|
-
|
110
|
+
if options.has_key?(:multiple_scopes) == false
|
111
|
+
options[:parameter] = favoritable_type
|
112
|
+
validate_scopes __method__, options
|
113
|
+
elsif options[:multiple_scopes] == true
|
114
|
+
results = {}
|
115
|
+
options[:scope].each do |scope|
|
116
|
+
favorites_scope = favorites_scoped(scope).for_favoritable_type favoritable_type
|
117
|
+
results[scope] = favorites_scope = apply_options_to_scope favorites_scope, options
|
118
|
+
end
|
119
|
+
return results
|
120
|
+
else
|
121
|
+
favorites_scope = favorites_scoped(options[:scope]).for_favoritable_type favoritable_type
|
122
|
+
return favorites_scope = apply_options_to_scope(favorites_scope, options)
|
123
|
+
end
|
53
124
|
end
|
54
125
|
|
55
126
|
# Returns the favorite records related to this instance with the favoritable included.
|
56
127
|
def all_favorites options = {}
|
57
|
-
|
58
|
-
|
128
|
+
if options.has_key?(:multiple_scopes) == false
|
129
|
+
validate_scopes __method__, options
|
130
|
+
elsif options[:multiple_scopes] == true
|
131
|
+
results = {}
|
132
|
+
options[:scope].each do |scope|
|
133
|
+
favorites_scope = favorites_scoped scope
|
134
|
+
results[scope] = favorites_scope = apply_options_to_scope favorites_scope, options
|
135
|
+
end
|
136
|
+
return results
|
137
|
+
else
|
138
|
+
favorites_scope = favorites_scoped options[:scope]
|
139
|
+
return favorites_scope = apply_options_to_scope(favorites_scope, options)
|
140
|
+
end
|
59
141
|
end
|
60
142
|
|
61
143
|
# Returns the actual records which this instance has favorited.
|
62
144
|
def all_favorited options = {}
|
63
|
-
all_favorites(options).collect{ |f| f.favoritable }
|
145
|
+
return all_favorites(options).collect{ |f| f.favoritable }
|
64
146
|
end
|
65
147
|
|
66
148
|
# Returns the actual records of a particular type which this record has fovarited.
|
67
149
|
def favorited_by_type favoritable_type, options = {}
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
150
|
+
if options.has_key?(:multiple_scopes) == false
|
151
|
+
options[:parameter] = favoritable_type
|
152
|
+
validate_scopes __method__, options
|
153
|
+
elsif options[:multiple_scopes] == true
|
154
|
+
results = {}
|
155
|
+
options[:scope].each do |scope|
|
156
|
+
favoritables = favoritable_type.constantize.joins(:favorited).where('favorites.blocked': false,
|
157
|
+
'favorites.favoritor_id': id,
|
158
|
+
'favorites.favoritor_type': parent_class_name(self),
|
159
|
+
'favorites.favoritable_type': favoritable_type,
|
160
|
+
'favorites.scope': scope)
|
161
|
+
if options.has_key? :limit
|
162
|
+
favoritables = favoritables.limit options[:limit]
|
163
|
+
end
|
164
|
+
if options.has_key? :includes
|
165
|
+
favoritables = favoritables.includes options[:includes]
|
166
|
+
end
|
167
|
+
results[scope] = favoritables
|
168
|
+
end
|
169
|
+
return results
|
170
|
+
else
|
171
|
+
favoritables = favoritable_type.constantize.joins(:favorited).where('favorites.blocked': false,
|
172
|
+
'favorites.favoritor_id': id,
|
173
|
+
'favorites.favoritor_type': parent_class_name(self),
|
174
|
+
'favorites.favoritable_type': favoritable_type,
|
175
|
+
'favorites.scope': options[:scope])
|
176
|
+
if options.has_key? :limit
|
177
|
+
favoritables = favoritables.limit options[:limit]
|
178
|
+
end
|
179
|
+
if options.has_key? :includes
|
180
|
+
favoritables = favoritables.includes options[:includes]
|
181
|
+
end
|
182
|
+
return favoritables
|
79
183
|
end
|
80
|
-
favoritables
|
81
184
|
end
|
82
185
|
|
83
|
-
def favorited_by_type_count favoritable_type
|
84
|
-
|
186
|
+
def favorited_by_type_count favoritable_type, options = {}
|
187
|
+
if options.has_key?(:multiple_scopes) == false
|
188
|
+
options[:parameter] = favoritable_type
|
189
|
+
validate_scopes __method__, options
|
190
|
+
elsif options[:multiple_scopes] == true
|
191
|
+
results = {}
|
192
|
+
options[:scope].each do |scope|
|
193
|
+
results[scope] = favorites.unblocked.send(scope + '_list').for_favoritable_type(favoritable_type).count
|
194
|
+
end
|
195
|
+
return results
|
196
|
+
else
|
197
|
+
return favorites.unblocked.send(options[:scope] + '_list').for_favoritable_type(favoritable_type).count
|
198
|
+
end
|
85
199
|
end
|
86
200
|
|
87
201
|
# Allows magic names on favorited_by_type
|
@@ -103,8 +217,19 @@ module ActsAsFavoritor #:nodoc:
|
|
103
217
|
end
|
104
218
|
|
105
219
|
# Returns a favorite record for the current instance and favoritable object.
|
106
|
-
def get_favorite favoritable
|
107
|
-
|
220
|
+
def get_favorite favoritable, options = {}
|
221
|
+
if options.has_key?(:multiple_scopes) == false
|
222
|
+
options[:parameter] = favoritable
|
223
|
+
validate_scopes __method__, options
|
224
|
+
elsif options[:multiple_scopes] == true
|
225
|
+
results = {}
|
226
|
+
options[:scope].each do |scope|
|
227
|
+
results[scope] = favorites.unblocked.send(scope + '_list').for_favoritable(favoritable).first
|
228
|
+
end
|
229
|
+
return results
|
230
|
+
else
|
231
|
+
return favorites.unblocked.send(options[:scope] + '_list').for_favoritable(favoritable).first
|
232
|
+
end
|
108
233
|
end
|
109
234
|
|
110
235
|
end
|
@@ -33,10 +33,24 @@ module ActsAsFavoritor
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def parent_classes
|
36
|
-
return DEFAULT_PARENTS
|
36
|
+
return DEFAULT_PARENTS
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
def validate_scopes method, options = {}
|
40
|
+
options[:scope] = options[:scope] || ['favorites']
|
41
|
+
if options[:scope].size > 1
|
42
|
+
options[:multiple_scopes] = true
|
43
|
+
else
|
44
|
+
options[:multiple_scopes] = false
|
45
|
+
options[:scope] = options[:scope][0]
|
46
|
+
end
|
47
|
+
if options.has_key? :parameter
|
48
|
+
parameter = options[:parameter]
|
49
|
+
options.delete :parameter
|
50
|
+
send method, parameter, options
|
51
|
+
else
|
52
|
+
send method, options
|
53
|
+
end
|
40
54
|
end
|
41
55
|
|
42
56
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Now run `rails db:migrate` to add acts_as_favoritor to your database.
|
@@ -3,7 +3,7 @@ class ActsAsFavoritorMigration < ActiveRecord::Migration<% if Rails::VERSION::MA
|
|
3
3
|
create_table :favorites, force: true do |t|
|
4
4
|
t.references :favoritable, polymorphic: true, null: false
|
5
5
|
t.references :favoritor, polymorphic: true, null: false
|
6
|
-
t.string :
|
6
|
+
t.string :scope, default: 'favorites', null: false
|
7
7
|
t.boolean :blocked, default: false, null: false
|
8
8
|
t.timestamps
|
9
9
|
end
|
@@ -13,6 +13,6 @@ class ActsAsFavoritorMigration < ActiveRecord::Migration<% if Rails::VERSION::MA
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.down
|
16
|
-
|
16
|
+
drop_table :favorites
|
17
17
|
end
|
18
18
|
end
|
@@ -3,8 +3,6 @@ class Favorite < ActiveRecord::Base
|
|
3
3
|
extend ActsAsFavoritor::FavoritorLib
|
4
4
|
extend ActsAsFavoritor::FavoriteScopes
|
5
5
|
|
6
|
-
serialize :scopes
|
7
|
-
|
8
6
|
# NOTE: Favorites belong to the 'favoritable' and 'favoritor' interface
|
9
7
|
belongs_to :favoritable, polymorphic: true
|
10
8
|
belongs_to :favoritor, polymorphic: true
|
@@ -82,8 +82,8 @@ class ActsAsFavoritableTest < ActiveSupport::TestCase
|
|
82
82
|
@jon.destroy
|
83
83
|
end
|
84
84
|
|
85
|
-
should_change
|
86
|
-
should_change
|
85
|
+
should_change('Favorite count', by: -1) { Favorite.count }
|
86
|
+
should_change('@sam.all_favorited.size', by: -1) { @sam.all_favorited.size }
|
87
87
|
end
|
88
88
|
|
89
89
|
context 'get favorite record' do
|
@@ -9,7 +9,7 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
9
9
|
|
10
10
|
should 'be defined' do
|
11
11
|
assert @sam.respond_to? :favorited?
|
12
|
-
assert @sam.respond_to? :
|
12
|
+
assert @sam.respond_to? :favorites_count
|
13
13
|
assert @sam.respond_to? :favorite
|
14
14
|
assert @sam.respond_to? :remove_favorite
|
15
15
|
assert @sam.respond_to? :favorites_by_type
|
@@ -28,13 +28,13 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
28
28
|
|
29
29
|
context 'favorited' do
|
30
30
|
should 'return favorited_status' do
|
31
|
-
assert_equal true, @sam.favorited?
|
32
|
-
assert_equal false, @jon.favorited?
|
31
|
+
assert_equal true, @sam.favorited?(@jon)
|
32
|
+
assert_equal false, @jon.favorited?(@sam)
|
33
33
|
end
|
34
34
|
|
35
|
-
should 'return
|
36
|
-
assert_equal 2, @sam.
|
37
|
-
assert_equal 0, @jon.
|
35
|
+
should 'return favorites_count' do
|
36
|
+
assert_equal 2, @sam.favorites_count
|
37
|
+
assert_equal 0, @jon.favorites_count
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -44,7 +44,7 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
44
44
|
end
|
45
45
|
|
46
46
|
should_change('Favorite count', by: 1) { Favorite.count }
|
47
|
-
should_change('@jon.
|
47
|
+
should_change('@jon.favorites_count', by: 1) { @jon.favorites_count }
|
48
48
|
|
49
49
|
should "set the favoritor" do
|
50
50
|
assert_equal @jon, Favorite.last.favoritor
|
@@ -61,7 +61,7 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
61
61
|
end
|
62
62
|
|
63
63
|
should_not_change('Favorite count') { Favorite.count }
|
64
|
-
should_not_change('@jon.
|
64
|
+
should_not_change('@jon.favorites_count') { @jon.favorites_count }
|
65
65
|
|
66
66
|
should 'not set the favoritor' do
|
67
67
|
assert_not_equal @jon, Favorite.last.favoritor
|
@@ -78,7 +78,7 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
78
78
|
end
|
79
79
|
|
80
80
|
should_change('Favorite count', by: -1) { Favorite.count }
|
81
|
-
should_change('@sam.
|
81
|
+
should_change('@sam.favorites_count', by: -1) { @sam.favorites_count }
|
82
82
|
end
|
83
83
|
|
84
84
|
context 'favorites' do
|
@@ -194,7 +194,7 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
194
194
|
end
|
195
195
|
|
196
196
|
should_change('Favorite.count', by: -1) { Favorite.count }
|
197
|
-
should_change('@sam.
|
197
|
+
should_change('@sam.favorites_count', by: -1) { @sam.favorites_count }
|
198
198
|
end
|
199
199
|
|
200
200
|
context "blocked by favoritable" do
|
@@ -206,8 +206,8 @@ class ActsAsFavoritorTest < ActiveSupport::TestCase
|
|
206
206
|
assert_equal false, @sam.favorited?(@jon)
|
207
207
|
end
|
208
208
|
|
209
|
-
should 'return
|
210
|
-
assert_equal 1, @sam.
|
209
|
+
should 'return favorites_count' do
|
210
|
+
assert_equal 1, @sam.favorites_count
|
211
211
|
end
|
212
212
|
|
213
213
|
should 'not return record of the blocked favorites' do
|
data/test/favorite_test.rb
CHANGED
@@ -7,22 +7,4 @@ class FavoriteTest < ActiveSupport::TestCase
|
|
7
7
|
assert true
|
8
8
|
end
|
9
9
|
|
10
|
-
context 'configuration with setters' do
|
11
|
-
should 'contain custom parents' do
|
12
|
-
ActsAsFavoritor.custom_parent_classes = [CustomRecord]
|
13
|
-
|
14
|
-
assert_equal [CustomRecord], ActsAsFavoritor.custom_parent_classes
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context '#setup' do
|
19
|
-
should 'contain custom parents via setup' do
|
20
|
-
ActsAsFavoritor.setup do |c|
|
21
|
-
c.custom_parent_classes = [CustomRecord]
|
22
|
-
end
|
23
|
-
|
24
|
-
assert_equal [CustomRecord], ActsAsFavoritor.custom_parent_classes
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
10
|
end
|
data/test/schema.rb
CHANGED
@@ -5,7 +5,7 @@ ActiveRecord::Schema.define version: 0 do
|
|
5
5
|
t.string 'favoritable_type', null: false
|
6
6
|
t.integer 'favoritor_id', null: false
|
7
7
|
t.string 'favoritor_type', null: false
|
8
|
-
t.string
|
8
|
+
t.string :scope, default: 'favorites', null: false
|
9
9
|
t.boolean 'blocked', default: false, null: false
|
10
10
|
t.datetime 'created_at'
|
11
11
|
t.datetime 'updated_at'
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_favoritor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Hübotter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '4.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tzinfo-data
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.2017'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.2017'
|
97
111
|
description: acts_as_favoritor is a Rubygem to allow any ActiveRecord model to favorite
|
98
112
|
any other model. This is accomplished through a double polymorphic relationship
|
99
113
|
on the Favorite model. There is also built in support for blocking/un-blocking favorite
|
@@ -104,9 +118,13 @@ executables: []
|
|
104
118
|
extensions: []
|
105
119
|
extra_rdoc_files: []
|
106
120
|
files:
|
121
|
+
- ".github/issue_template.md"
|
122
|
+
- ".github/pull_request_template.md"
|
107
123
|
- ".gitignore"
|
108
124
|
- ".travis.yml"
|
109
|
-
-
|
125
|
+
- CODE_OF_CONDUCT.md
|
126
|
+
- CONTRIBUTING.md
|
127
|
+
- DEPRECATIONS.md
|
110
128
|
- Gemfile
|
111
129
|
- LICENSE
|
112
130
|
- README.md
|
@@ -120,11 +138,10 @@ files:
|
|
120
138
|
- lib/acts_as_favoritor/favoritor_lib.rb
|
121
139
|
- lib/acts_as_favoritor/railtie.rb
|
122
140
|
- lib/acts_as_favoritor/version.rb
|
123
|
-
- lib/generators/USAGE
|
124
141
|
- lib/generators/acts_as_favoritor_generator.rb
|
142
|
+
- lib/generators/templates/README.md
|
125
143
|
- lib/generators/templates/migration.rb.erb
|
126
144
|
- lib/generators/templates/model.rb
|
127
|
-
- test/README
|
128
145
|
- test/acts_as_favoritable_test.rb
|
129
146
|
- test/acts_as_favoritor_test.rb
|
130
147
|
- test/dummy30/Gemfile
|
data/CHANGELOG.md
DELETED
data/lib/generators/USAGE
DELETED
data/test/README
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
Testing
|
2
|
-
=======
|
3
|
-
|
4
|
-
Tests are written with Shoulda on top of Test::Unit and Factory Girl is used instead of fixtures. Tests are run using rake.
|
5
|
-
|
6
|
-
1. Clone your fork git locally.
|
7
|
-
2. Install the dependencies
|
8
|
-
$ bundle install
|
9
|
-
3. Run the tests:
|
10
|
-
rake test
|
11
|
-
|
12
|
-
|
13
|
-
Coverage
|
14
|
-
=======
|
15
|
-
|
16
|
-
Test coverage can be calculated using Rcov. Make sure you have the rcov gem installed.
|
17
|
-
|
18
|
-
Again in the acts_as_favoritor directory:
|
19
|
-
|
20
|
-
rake rcov:gen DB=sqlite3 # For sqlite
|
21
|
-
|
22
|
-
The coverage will now be available in the test/coverage directory.
|
23
|
-
|
24
|
-
rake rcov:clobber will delete the coverage directory.
|