basic_named_scopes 0.1.0
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.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/README.rdoc +81 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/lib/basic_named_scopes.rb +63 -0
- data/spec/basic_named_scopes_spec.rb +58 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +15 -0
- metadata +83 -0
data/.document
ADDED
data/.gitignore
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= BasicNamedScopes
|
2
|
+
|
3
|
+
Basic named scopes for ActiveRecord. Propagates the parameters of the
|
4
|
+
find-method as named scopes, for easy reusability and prettier code.
|
5
|
+
|
6
|
+
Instead of writing:
|
7
|
+
|
8
|
+
Post.all(:conditions => { :published => true }, :select => :title, :includes => :author)
|
9
|
+
|
10
|
+
You can now write:
|
11
|
+
|
12
|
+
Post.conditions(:published => true).select(:title).include(:author)
|
13
|
+
|
14
|
+
Reuse them by making class methods:
|
15
|
+
|
16
|
+
class Post < ActiveRecord::Base
|
17
|
+
|
18
|
+
def self.published
|
19
|
+
conditions(:published => true)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.visible
|
23
|
+
conditions(:visible => true)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.index
|
27
|
+
published.visible
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
Also, the +all+-method is a named scope now, so you can chain after callling
|
33
|
+
all, for greater flexibility.
|
34
|
+
|
35
|
+
Post.all.published
|
36
|
+
|
37
|
+
Arrays can be used as multple parameters too, sparing you some brackets.
|
38
|
+
|
39
|
+
Post.include(:author, :comments).conditions("name LIKE ?", query)
|
40
|
+
|
41
|
+
The +read_only+ and +lock+ scopes default to true, but can be adjusted.
|
42
|
+
|
43
|
+
Post.readonly # => same as Post.all(:readonly => true)
|
44
|
+
Post.readonly(false) # => same as Post.all(:readonly => false)
|
45
|
+
|
46
|
+
== Why?
|
47
|
+
|
48
|
+
NamedScopes are really handy and they should play a more central theme in ActiveRecord.
|
49
|
+
While I heard that ActiveRecord 3 will support similar syntax, there is no reason to wait
|
50
|
+
any longer.
|
51
|
+
|
52
|
+
I find defining named scopes very ugly, especially when dealing with parameters.
|
53
|
+
Just compare the amount of curly braces!
|
54
|
+
|
55
|
+
# Using normal named scope:
|
56
|
+
named_scope :name_like, lambda { |query| { :conditions => ["name LIKE ?", query] } }
|
57
|
+
|
58
|
+
# Using BasicNamedScopes
|
59
|
+
def self.name_like(query)
|
60
|
+
conditions("name LIKE ?", query)
|
61
|
+
end
|
62
|
+
|
63
|
+
Also, regular named scopes don't support using other named scopes at all!
|
64
|
+
|
65
|
+
I found myself implementing (mostly conditions, but others too) so often, that
|
66
|
+
a little gem like this would be the obvious choice. Use it if a gem like
|
67
|
+
searchlogic is overkill for your needs.
|
68
|
+
|
69
|
+
== Installing
|
70
|
+
|
71
|
+
The gem is called "basic_named_scopes". You know how to install it.
|
72
|
+
|
73
|
+
gem install basic_named_scopes
|
74
|
+
|
75
|
+
Use it in Rails:
|
76
|
+
|
77
|
+
config.gem "basic_named_scopes"
|
78
|
+
|
79
|
+
== Copyright
|
80
|
+
|
81
|
+
Copyright (c) 2009 Iain Hecker. Released under the MIT License.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "basic_named_scopes"
|
8
|
+
gem.summary = %Q{Basic named scopes for ActiveRecord makes all find-parameters a named scope}
|
9
|
+
gem.description = %Q{Make your queries prettier and more reusable by having a named scope for every find-parameter. As easy as Post.include(:author, :comments)}
|
10
|
+
gem.email = "iain@iain.nl"
|
11
|
+
gem.homepage = "http://github.com/iain/basic_named_scopes"
|
12
|
+
gem.authors = ["Iain Hecker"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
gem.add_development_dependency "temping", ">= 1.1.0"
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'spec/rake/spectask'
|
22
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
25
|
+
end
|
26
|
+
|
27
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
28
|
+
spec.libs << 'lib' << 'spec'
|
29
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
30
|
+
spec.rcov = true
|
31
|
+
end
|
32
|
+
|
33
|
+
task :spec => :check_dependencies
|
34
|
+
|
35
|
+
task :default => :spec
|
36
|
+
|
37
|
+
require 'rake/rdoctask'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "basic_named_scopes #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Basic named scopes for ActiveRecord. Propagates the parameters of the
|
2
|
+
# find-method as named scopes, for easy reusability and prettier code.
|
3
|
+
#
|
4
|
+
# Instead of writing:
|
5
|
+
#
|
6
|
+
# Post.all(:conditions => { :published => true }, :select => :title, :includes => :author)
|
7
|
+
#
|
8
|
+
# You can now write:
|
9
|
+
#
|
10
|
+
# Post.conditions(:published => true).select(:title).include(:author)
|
11
|
+
#
|
12
|
+
# Reuse them by making class methods:
|
13
|
+
#
|
14
|
+
# class Post < ActiveRecord::Base
|
15
|
+
#
|
16
|
+
# def self.published
|
17
|
+
# conditions(:published => true)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def self.visible
|
21
|
+
# conditions(:visible => true)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def self.index
|
25
|
+
# published.visible
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# Also, the +all+-method is a named scope now, so you can chain after callling
|
31
|
+
# all, for greater flexibility.
|
32
|
+
#
|
33
|
+
# Post.all.published
|
34
|
+
#
|
35
|
+
# Arrays can be used as multple parameters too, sparing you some brackets.
|
36
|
+
#
|
37
|
+
# Post.include(:author, :comments).conditions("name LIKE ?", query)
|
38
|
+
#
|
39
|
+
# The +read_only+ and +lock+ scopes default to true, but can be adjusted.
|
40
|
+
#
|
41
|
+
# Post.readonly # => same as Post.all(:readonly => true)
|
42
|
+
# Post.readonly(false) # => same as Post.all(:readonly => false)
|
43
|
+
#
|
44
|
+
module BasicNamedScopes
|
45
|
+
|
46
|
+
FIND_PARAMETERS = [:conditions, :order, :group, :having, :limit, :offset, :joins, :include, :select, :from]
|
47
|
+
FIND_BOOLEAN_SWITCHES = [:readonly, :lock]
|
48
|
+
|
49
|
+
def self.extended(record)
|
50
|
+
FIND_PARAMETERS.each do |parameter|
|
51
|
+
record.named_scope(parameter, lambda { |*args| { parameter => args.size == 1 ? args.first : args } })
|
52
|
+
end
|
53
|
+
FIND_BOOLEAN_SWITCHES.each do |parameter|
|
54
|
+
record.named_scope(parameter, lambda { |*args| { parameter => args.size == 0 ? true : args[0] } })
|
55
|
+
end
|
56
|
+
record.named_scope(:all, lambda { |*args| args[0] || {} })
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
if defined? ActiveRecord
|
62
|
+
ActiveRecord::Base.extend(BasicNamedScopes)
|
63
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "BasicNamedScopes" do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
create_model :posts do
|
7
|
+
with_columns do |table|
|
8
|
+
table.boolean :published
|
9
|
+
table.boolean :visible
|
10
|
+
end
|
11
|
+
extend BasicNamedScopes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
Post.delete_all
|
17
|
+
@published = Post.create!(:published => true)
|
18
|
+
@unpublished = Post.create!(:published => false)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should make .all a named scope" do
|
22
|
+
# Without parameters
|
23
|
+
Post.all.class.should be_scope
|
24
|
+
# With parameters
|
25
|
+
Post.all(:conditions => {:published => true}).class.should be_scope
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should make find parameters a named scope" do
|
29
|
+
subject = Post.conditions(:published => true)
|
30
|
+
subject.class.should be_scope
|
31
|
+
subject.should == [ @published ]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should expand into array when using multiple parameters" do
|
35
|
+
subject = Post.conditions("published = ?", true)
|
36
|
+
subject.class.should be_scope
|
37
|
+
subject.should == [ @published ]
|
38
|
+
end
|
39
|
+
|
40
|
+
[:conditions, :order, :group, :having, :limit, :offset, :joins, :include, :select, :from].each do |option|
|
41
|
+
it "should known #{option} ActiveRecord::Base.find" do
|
42
|
+
Post.send(option).class.should be_scope
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should default to true for readonly" do
|
47
|
+
subject = Post.readonly
|
48
|
+
subject.class.should be_scope
|
49
|
+
lambda { subject.first.save }.should raise_error(ActiveRecord::ReadOnlyRecord)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should accept a value for readonly" do
|
53
|
+
subject = Post.readonly(false)
|
54
|
+
subject.class.should be_scope
|
55
|
+
lambda { subject.first.save }.should_not raise_error(ActiveRecord::ReadOnlyRecord)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'basic_named_scopes'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
require 'active_record'
|
7
|
+
require 'temping'
|
8
|
+
|
9
|
+
Spec::Runner.configure do |config|
|
10
|
+
config.include(Temping)
|
11
|
+
end
|
12
|
+
|
13
|
+
def be_scope
|
14
|
+
eql(ActiveRecord::NamedScope::Scope)
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: basic_named_scopes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Iain Hecker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-19 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.9
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: temping
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.1.0
|
34
|
+
version:
|
35
|
+
description: Make your queries prettier and more reusable by having a named scope for every find-parameter. As easy as Post.include(:author, :comments)
|
36
|
+
email: iain@iain.nl
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- .document
|
45
|
+
- .gitignore
|
46
|
+
- README.rdoc
|
47
|
+
- Rakefile
|
48
|
+
- VERSION
|
49
|
+
- lib/basic_named_scopes.rb
|
50
|
+
- spec/basic_named_scopes_spec.rb
|
51
|
+
- spec/spec.opts
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://github.com/iain/basic_named_scopes
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.5
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Basic named scopes for ActiveRecord makes all find-parameters a named scope
|
81
|
+
test_files:
|
82
|
+
- spec/basic_named_scopes_spec.rb
|
83
|
+
- spec/spec_helper.rb
|