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.
@@ -0,0 +1,2 @@
1
+ spec/debug.log
2
+ spec/db/active_record_helpers.sqlite3.db
@@ -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
+
@@ -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
@@ -0,0 +1,2 @@
1
+ ActiveRecord::Base.send(:include, ActiveRecordHelpers)
2
+ Object.send(:include, ObjectHelpers)
@@ -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
@@ -0,0 +1,3 @@
1
+ sqlite3:
2
+ :adapter: sqlite3
3
+ :database: vendor/plugins/active_record_helpers/spec/db/active_record_helpers.sqlite3.db
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :players, :force => true do |t|
3
+ t.column :name, :string
4
+ t.column :rating, :integer, :default => 0
5
+ end
6
+ end
@@ -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