active_record_helpers 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/.gitignore +2 -0
- data/README.rdoc +72 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/active_record_helpers.rb +68 -0
- data/lib/object_helpers.rb +12 -0
- data/rails/init.rb +2 -0
- data/spec/active_record_helpers_spec.rb +79 -0
- data/spec/db/database.yml +3 -0
- data/spec/db/schema.rb +6 -0
- data/spec/spec_helper.rb +12 -0
- metadata +68 -0
data/.gitignore
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
active_record_helpers plugin provides a bunch of helpful methods.
|
2
|
+
|
3
|
+
== Class Methods
|
4
|
+
|
5
|
+
=== ids(field = "id")
|
6
|
+
|
7
|
+
Returns an array of the values of field converted to Integer
|
8
|
+
|
9
|
+
>> Deathmatch.finished.recent.ids
|
10
|
+
=> [505, 501, 500]
|
11
|
+
>> Deathmatch.finished.recent.ids(:map_id)
|
12
|
+
=> [4, 4, 6]
|
13
|
+
|
14
|
+
=== attribute(field)
|
15
|
+
|
16
|
+
Returns an array of the field's raw values
|
17
|
+
|
18
|
+
>> Player.scoped(:limit => 3, :order => 'rating desc').attribute(:name)
|
19
|
+
=> ["boffy", "pitibo", "macovsky"]
|
20
|
+
|
21
|
+
=== attributes(fields)
|
22
|
+
|
23
|
+
Returns an array of record hashes with the column names as keys and column raw values as values
|
24
|
+
|
25
|
+
>> Deathmatch.finished.last.players.scoped(:limit => 3, :order => 'frags desc').attributes(:name, :frags)
|
26
|
+
=> [{"name" => "boffy", :frags => "35"}, {"name" => "pitibo", "frags" => "34"}, {"name" => "macovsky", "frags" => "33"}]
|
27
|
+
|
28
|
+
All of these methods work fast because they don't instantiate ActiveRecord objects.
|
29
|
+
|
30
|
+
They were originally made by Max Lapshin — http://github.com/maxlapshin
|
31
|
+
|
32
|
+
=== update_all_counters
|
33
|
+
|
34
|
+
Works as update_counters, but accepts the same arguments as update_all method. Consider examples:
|
35
|
+
|
36
|
+
Flow.update_all_counters({:rating => 1}, {:id => 3})
|
37
|
+
Flow.update_all_counters({:rating => 1, :votes_left => -1}, ["user_id=?", 3])
|
38
|
+
Post.update_all_counters({:rating => 1}, :order => "created_at", :limit => 100)
|
39
|
+
|
40
|
+
=== select_fields
|
41
|
+
|
42
|
+
Returns SQL-text for passing to :select option in finder
|
43
|
+
|
44
|
+
>> Player.select_fields(%w{id name frags})
|
45
|
+
=> "players.id, players.title, players.permalink"
|
46
|
+
>> Deathmatch.select_fields('id', 'players.name as winner_name')
|
47
|
+
=> "deathmatches.id, players.name as winner_name"
|
48
|
+
|
49
|
+
== Instance Methods
|
50
|
+
|
51
|
+
=== to_poly_params
|
52
|
+
|
53
|
+
Returns a hash for polymorphic conditions
|
54
|
+
|
55
|
+
>> User.first.to_poly_params
|
56
|
+
=> {:resource_type=>"User", :resource_id=>3}
|
57
|
+
>> User.first.to_poly_params('post')
|
58
|
+
=> {:post_id=>3, :post_type=>"User"}
|
59
|
+
|
60
|
+
=== Object#get_id
|
61
|
+
|
62
|
+
It also adds a get_id method to Object useful in methods which can receive either an ActiveRecord instance or its id.
|
63
|
+
|
64
|
+
>> User.last.get_id
|
65
|
+
=> 5
|
66
|
+
>> 5.get_id
|
67
|
+
=> 5
|
68
|
+
|
69
|
+
== Installation
|
70
|
+
|
71
|
+
script/plugin install git://github.com/robotector/active_record_helpers.git
|
72
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "active_record_helpers"
|
8
|
+
gemspec.summary = "A bunch of helpful methods for ActiveRecord"
|
9
|
+
gemspec.description = "A bunch of helpful methods for ActiveRecord"
|
10
|
+
gemspec.email = "robotector@gmail.com"
|
11
|
+
gemspec.homepage = "http://github.com/macovsky/active_record_helpers"
|
12
|
+
gemspec.authors = ["Macovsky"]
|
13
|
+
end
|
14
|
+
Jeweler::GemcutterTasks.new
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
# require 'rake'
|
20
|
+
# require 'spec/rake/spectask'
|
21
|
+
#
|
22
|
+
# desc 'Default: run specs.'
|
23
|
+
# task :default => :spec
|
24
|
+
#
|
25
|
+
# desc 'Run the specs'
|
26
|
+
# Spec::Rake::SpecTask.new(:spec) do |t|
|
27
|
+
# t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
28
|
+
# t.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
# end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init.rb"
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module ActiveRecordHelpers
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
# Returns an array of the values of field converted to Integer
|
9
|
+
# Works fast because it doesn't instantiate records and it goes well with scopes
|
10
|
+
# >> Deathmatch.finished.recent.ids
|
11
|
+
# => [505, 501, 500]
|
12
|
+
# >> Deathmatch.finished.recent.ids(:map_id)
|
13
|
+
# => [4, 4, 6]
|
14
|
+
def ids(field = "id")
|
15
|
+
attribute(field).map(&:to_i)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns an array of the field's raw values
|
19
|
+
# Works fast because it doesn't instantiate records and it goes well with scopes
|
20
|
+
# >> Player.scoped(:limit => 3, :order => 'rating desc').attribute(:name)
|
21
|
+
# => ["boffy", "pitibo", "macovsky"]
|
22
|
+
def attribute(field)
|
23
|
+
connection.select_values(send(:construct_finder_sql, :select => field))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an array of record hashes with the column names as keys and column raw values as values
|
27
|
+
# Works fast because it doesn't instantiate records and it goes well with scopes
|
28
|
+
# >> Deathmatch.finished.last.players.scoped(:limit => 3, :order => 'frags desc').attributes(:name, :frags)
|
29
|
+
# => [{"name" => "boffy", "frags" => "35"}, {"name" => "pitibo", "frags" => "34"}, {"name" => "macovsky", "frags" => "33"}]
|
30
|
+
def attributes(*fields)
|
31
|
+
connection.send(:select_all, send(:construct_finder_sql, :select => select_fields(fields)))
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns SQL-text for passing to :select option in finder
|
35
|
+
# >> Player.select_fields(%w{id name frags})
|
36
|
+
# => "players.id, players.title, players.permalink"
|
37
|
+
# >> Deathmatch.select_fields('id', 'players.name as winner_name')
|
38
|
+
# => "deathmatches.id, players.name as winner_name"
|
39
|
+
def select_fields(*fields)
|
40
|
+
Array(fields).flatten.map{|field| column_names.include?(field.to_s) ? "#{table_name}.#{field}" : field }.join(', ')
|
41
|
+
end
|
42
|
+
|
43
|
+
# Updates counters but accepts the same arguments as update_all method
|
44
|
+
# Flow.update_all_counters({:rating => 1}, {:id => 3})
|
45
|
+
# Flow.update_all_counters({:rating => 1, :votes_left => -1}, ["user_id=?", 3])
|
46
|
+
# Post.update_all_counters({:rating => 1}, :order => "created_at", :limit => 100)
|
47
|
+
def update_all_counters(counters, conditions = nil, options = {})
|
48
|
+
raise(ArgumentError, "counters should be provided in Hash") unless counters.is_a?(Hash)
|
49
|
+
|
50
|
+
updates = counters.inject([]) { |list, (counter_name, increment)|
|
51
|
+
sign = increment < 0 ? "-" : "+"
|
52
|
+
list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
|
53
|
+
}.join(", ")
|
54
|
+
|
55
|
+
update_all(updates, conditions, options)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# returns a hash for polymorphic conditions
|
61
|
+
# >> User.first.to_poly_params
|
62
|
+
# => {:resource_type=>"User", :resource_id=>3}
|
63
|
+
# >> User.first.to_poly_params('post')
|
64
|
+
# => {:post_id=>3, :post_type=>"User"}
|
65
|
+
def to_poly_params(prefix = 'resource')
|
66
|
+
eval("{:#{prefix}_id => #{self.id}, :#{prefix}_type => '#{self.class.base_class}'}")
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ObjectHelpers
|
2
|
+
# using this method you can pass either an ActiveRecord object or it's id
|
3
|
+
# >> User.last.get_id
|
4
|
+
# => 5
|
5
|
+
# >> 5.get_id
|
6
|
+
# => 5
|
7
|
+
# >> nil.get_id
|
8
|
+
# => nil
|
9
|
+
def get_id(field="id")
|
10
|
+
is_a?(ActiveRecord::Base) ? send(field) : (self ? self.to_i : self)
|
11
|
+
end
|
12
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class Player < ActiveRecord::Base
|
4
|
+
end
|
5
|
+
|
6
|
+
describe ActiveRecordHelpers do
|
7
|
+
|
8
|
+
context "with db" do
|
9
|
+
|
10
|
+
before do
|
11
|
+
['boffy', 30, 'pitibo', 29, 'macovsky', 21].in_groups_of(2) do |group|
|
12
|
+
Player.create(:name => group[0], :rating => group[1])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "ids should return players' ids" do
|
17
|
+
Player.ids.should == Player.all.map(&:id)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "ids(:rating) should return players' ratings as integers" do
|
21
|
+
Player.ids(:rating).should == Player.all.map(&:rating)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "attribute should return an array of players' attributes" do
|
25
|
+
Player.attribute(:name).should == Player.all.map(&:name)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "attributes should return an array of players' attributes in hashes" do
|
29
|
+
Player.attributes(:name, :rating).should == Player.all.map{|p| p.attributes_before_type_cast.slice("name", "rating")}
|
30
|
+
end
|
31
|
+
|
32
|
+
context "update_all_counters" do
|
33
|
+
it "should update a rating of one player" do
|
34
|
+
lambda {
|
35
|
+
Player.update_all_counters({:rating => 1}, {:name => 'boffy'})
|
36
|
+
}.should change{Player.find_by_name('boffy').rating}.by(1)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should update ratings of all players" do
|
40
|
+
lambda {
|
41
|
+
Player.update_all_counters(:rating => 1)
|
42
|
+
}.should change{Player.ids(:rating)}.to([31, 30, 22])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "to_poly_params" do
|
47
|
+
before do
|
48
|
+
@player = Player.first
|
49
|
+
end
|
50
|
+
it "should return a hash of polymorphic conditions" do
|
51
|
+
@player.to_poly_params.should == {:resource_type => 'Player', :resource_id => @player.id}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return a hash of polymorphic conditions with defined prefix" do
|
55
|
+
@player.to_poly_params(:commentable).should == {:commentable_type => 'Player', :commentable_id => @player.id}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "get_id" do
|
60
|
+
it "should return an id of ActiveRecord object" do
|
61
|
+
@player = Player.first
|
62
|
+
|
63
|
+
@player.get_id.should == @player.id
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return a to_i" do
|
67
|
+
"5".get_id.should == 5
|
68
|
+
5.get_id.should == 5
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should return nil" do
|
72
|
+
nil.get_id.should == nil
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
data/spec/db/schema.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
begin
|
2
|
+
require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
|
3
|
+
rescue LoadError
|
4
|
+
puts "You need to install rspec in your base app"
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
plugin_spec_dir = File.dirname(__FILE__)
|
9
|
+
|
10
|
+
databases = YAML::load(IO.read(plugin_spec_dir + "/db/database.yml"))
|
11
|
+
ActiveRecord::Base.establish_connection(databases[ENV["db"] || "sqlite3"])
|
12
|
+
load(File.join(plugin_spec_dir, "db", "schema.rb"))
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_record_helpers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Macovsky
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-07 00:00:00 +03:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A bunch of helpful methods for ActiveRecord
|
17
|
+
email: robotector@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- README.rdoc
|
27
|
+
- Rakefile
|
28
|
+
- VERSION
|
29
|
+
- init.rb
|
30
|
+
- lib/active_record_helpers.rb
|
31
|
+
- lib/object_helpers.rb
|
32
|
+
- rails/init.rb
|
33
|
+
- spec/active_record_helpers_spec.rb
|
34
|
+
- spec/db/database.yml
|
35
|
+
- spec/db/schema.rb
|
36
|
+
- spec/spec_helper.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/macovsky/active_record_helpers
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: A bunch of helpful methods for ActiveRecord
|
65
|
+
test_files:
|
66
|
+
- spec/active_record_helpers_spec.rb
|
67
|
+
- spec/db/schema.rb
|
68
|
+
- spec/spec_helper.rb
|