arel_date_scopes 0.0.2

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/tmp/*/**
2
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --backtrace
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ arel_date_scopes (0.0.2)
5
+ activerecord (~> 3.0.0)
6
+ activesupport (~> 3.0.0)
7
+ arel (>= 2)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activemodel (3.0.5)
13
+ activesupport (= 3.0.5)
14
+ builder (~> 2.1.2)
15
+ i18n (~> 0.4)
16
+ activerecord (3.0.5)
17
+ activemodel (= 3.0.5)
18
+ activesupport (= 3.0.5)
19
+ arel (~> 2.0.2)
20
+ tzinfo (~> 0.3.23)
21
+ activesupport (3.0.5)
22
+ arel (2.0.9)
23
+ builder (2.1.2)
24
+ diff-lcs (1.1.2)
25
+ i18n (0.5.0)
26
+ rspec (2.5.0)
27
+ rspec-core (~> 2.5.0)
28
+ rspec-expectations (~> 2.5.0)
29
+ rspec-mocks (~> 2.5.0)
30
+ rspec-core (2.5.1)
31
+ rspec-expectations (2.5.0)
32
+ diff-lcs (~> 1.1.2)
33
+ rspec-mocks (2.5.0)
34
+ sqlite3 (1.3.3)
35
+ sqlite3-ruby (1.3.3)
36
+ sqlite3 (>= 1.3.3)
37
+ tzinfo (0.3.25)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ arel_date_scopes!
44
+ rspec
45
+ sqlite3-ruby
@@ -0,0 +1,51 @@
1
+ = Arel Date Scopes
2
+
3
+ This gem is useful when you want to navigate through your records by years, months or days - for example, at news archive page.
4
+
5
+ * AREL 2 date functions (DATE(), YEAR(), DAYOFMONTH() for MySQL, CAST(STRFTIME(...)) for SQLite)
6
+ * AR 3 scopes.
7
+
8
+ = Installation
9
+
10
+ Put following line in your Gemfile:
11
+
12
+ gem 'arel_date_scopes'
13
+
14
+ = Pure AREL example:
15
+
16
+ Let the users table have created_at field.
17
+
18
+ users = Table[:users]
19
+ users.where(users[:created_at].year.eq(2009))
20
+ users.where(users[:created_at].month.gt(2))
21
+ users.where(users[:created_at].dayofmonth.in(1..20))
22
+
23
+ = AR example:
24
+
25
+ Let the news table have created_at field and contain news for two years: 2008 and 2009.
26
+
27
+ class News < ActiveRecord::Base
28
+ date_scopes_for :created_at # Creates scopes for created_at field.
29
+ end
30
+
31
+ The News model gets the following scopes:
32
+
33
+ * created_at_year_eq
34
+ * created_at_month_eq
35
+ * created_at_day_eq
36
+ * created_at_years
37
+ * created_at_months
38
+ * created_at_days
39
+ * ascend_by_created_at
40
+ * descend_by_created_at
41
+
42
+ Usage example:
43
+
44
+ News.created_at_year_eq(2009).all
45
+ News.created_at_year_eq(2009).created_at_month_eq(5).all
46
+ News.descend_by_created_at.created_at_years.all.first['created_at_year'] # 2009
47
+ News.ascend_by_created_at.created_at_years.all_column # [2008, 2009]
48
+
49
+ = TODO:
50
+
51
+ * Create scopes through method_missing like searchlogic.
@@ -0,0 +1,10 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+ require 'arel_date_scopes'
6
+ require 'bundler'
7
+
8
+ Bundler::GemHelper.install_tasks
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ task :default => :spec
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "arel_date_scopes/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{arel_date_scopes}
8
+ s.version = ArelDateScopes::VERSION
9
+
10
+ s.authors = ["Victor Sokolov"]
11
+ s.description = %q{SQL date functions for AREL 2 + AR 3 scopes (such as created_at_year_eq)}
12
+ s.email = %q{gzigzigzeo@gmail.com}
13
+ s.homepage = %q{http://github.com/gzigzigzeo/arel_date_scopes}
14
+ s.rdoc_options = ["--charset=UTF-8"]
15
+ s.summary = %q{SQL date functions for AREL 2 + AR 3 date scopes (such as created_at_year_eq)}
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'arel', '>= 2'
23
+ s.add_dependency 'activerecord', '~> 3.0.0'
24
+ s.add_dependency 'activesupport', '~> 3.0.0'
25
+
26
+ s.add_development_dependency('sqlite3-ruby')
27
+ s.add_development_dependency('rspec')
28
+ end
@@ -0,0 +1,6 @@
1
+ module ArelDateScopes
2
+ require 'arel_date_scopes/version'
3
+ require 'arel_date_scopes/arel'
4
+ require 'arel_date_scopes/active_record'
5
+ require 'arel_date_scopes/railtie' if defined?(Rails)
6
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_support/concern'
4
+
5
+ module ArelDateScopes
6
+ module ActiveRecord
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def date_scopes_for(field)
11
+ scope :"#{field}_year_eq", lambda { |year|
12
+ t = arel_table
13
+ where(t[field].year.eq(year))
14
+ }
15
+
16
+ scope :"#{field}_month_eq", lambda { |month|
17
+ t = arel_table
18
+ where(t[field].month.eq(month))
19
+ }
20
+
21
+ scope :"#{field}_day_eq", lambda { |day|
22
+ t = arel_table
23
+ where(t[field].dayofmonth.eq(day))
24
+ }
25
+
26
+ scope :"#{field}_years", lambda {
27
+ t = arel_table
28
+ select(t[field].year.as("#{field}_year")).group(t[field].year)
29
+ }
30
+
31
+ scope :"#{field}_months", lambda {
32
+ t = arel_table
33
+ select(t[field].month.as("#{field}_month")).group(t[field].month)
34
+ }
35
+
36
+ scope :"#{field}_days", lambda {
37
+ t = arel_table
38
+ select(t[field].dayofmonth.as("#{field}_day")).group(t[field].dayofmonth)
39
+ }
40
+
41
+ scope :"descend_by_#{field}", order("#{field} DESC")
42
+ scope :"ascend_by_#{field}", order("#{field} ASC")
43
+ end
44
+
45
+ def all_column(field = nil)
46
+ rows = scoped.all
47
+ return [] if rows.empty?
48
+ field ||= rows.first.attributes.keys.first
49
+ rows.map { |row| row[field] }
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,83 @@
1
+ require 'arel'
2
+
3
+ module ArelDateScopes
4
+ # Workaround for Rails. Rails tries to threat left operands of == as Attribute object, but it can be
5
+ # a function like YEAR(). Fake #name should return "#{field}_#{function}" to resolve field conflicts.
6
+ module ArelAttributeEmulation
7
+ def name; self.expressions.first.name.to_s + '_' + self.class.name.underscore; end
8
+ def relation; self.expressions.first; end
9
+ end
10
+ end
11
+
12
+ module Arel
13
+ module Nodes
14
+ class Year < Arel::Nodes::Function
15
+ include Arel::Predications
16
+ include ArelDateScopes::ArelAttributeEmulation
17
+ end
18
+
19
+ class Month < Arel::Nodes::Function
20
+ include Arel::Predications
21
+ include ArelDateScopes::ArelAttributeEmulation
22
+ end
23
+
24
+ class DayOfMonth < Arel::Nodes::Function
25
+ include Arel::Predications
26
+ include ArelDateScopes::ArelAttributeEmulation
27
+ end
28
+ end
29
+
30
+ module Attributes
31
+ class Time
32
+ def year
33
+ Nodes::Year.new [self]
34
+ end
35
+
36
+ def month
37
+ Nodes::Month.new [self]
38
+ end
39
+
40
+ def dayofmonth
41
+ Nodes::DayOfMonth.new [self]
42
+ end
43
+ end
44
+ end
45
+
46
+ module Visitors
47
+ class SQLite
48
+ private
49
+ def visit_Arel_Nodes_Year o
50
+ "CAST(STRFTIME('%Y', #{o.expressions.map { |x|
51
+ visit x }.join(', ')}) AS INTEGER)#{o.alias ? " AS #{visit o.alias}" : ''}"
52
+ end
53
+
54
+ def visit_Arel_Nodes_Month o
55
+ "CAST(STRFTIME('%m', #{o.expressions.map { |x|
56
+ visit x }.join(', ')}) AS INTEGER)#{o.alias ? " AS #{visit o.alias}" : ''}"
57
+ end
58
+
59
+ def visit_Arel_Nodes_DayOfMonth o
60
+ "CAST(STRFTIME('%d', #{o.expressions.map { |x|
61
+ visit x }.join(', ')}) AS INTEGER)#{o.alias ? " AS #{visit o.alias}" : ''}"
62
+ end
63
+ end
64
+
65
+ class MySQL
66
+ private
67
+ def visit_Arel_Nodes_Year o
68
+ "YEAR(#{o.expressions.map { |x|
69
+ visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
70
+ end
71
+
72
+ def visit_Arel_Nodes_Month o
73
+ "MONTH(#{o.expressions.map { |x|
74
+ visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
75
+ end
76
+
77
+ def visit_Arel_Nodes_DayOfMonth o
78
+ "DAYOFMONTH(#{o.expressions.map { |x|
79
+ visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ module ArelDateScopes
2
+ class Railtie < Rails::Railtie
3
+ initializer 'arel_date_scopes.insert_into_active_record' do
4
+ ActiveSupport.on_load :active_record do
5
+ ::ActiveRecord::Base.send(:include, ArelDateScopes::ActiveRecord)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module ArelDateScopes
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe "date_scopes AREL extensions" do
4
+ before(:each) { @table = Arel::Table.new(:users) }
5
+
6
+ context("for MySQL") do
7
+ before(:each) do
8
+ @visitor = Arel::Visitors::MySQL.new(Arel::Sql::Engine.new(FakeRecord::Base.new('mysql')))
9
+ end
10
+
11
+ it "should correctly transform to_sql DATE, MONTH, DAYOFMONTH" do
12
+ @visitor.accept(@table[:created_at].year.eq(2009)).should eq('YEAR("users"."created_at") = 2009')
13
+ @visitor.accept(@table[:created_at].month.in(1..12)).should eq('MONTH("users"."created_at") BETWEEN 1 AND 12')
14
+ @visitor.accept(@table[:created_at].dayofmonth.gt(10)).should eq('DAYOFMONTH("users"."created_at") > 10')
15
+ @table.project(@table[:created_at].year).group(@table[:created_at].year).to_sql.should
16
+ eq('SELECT YEAR("users"."created_at") FROM "users" GROUP BY YEAR("users"."created_at")')
17
+ end
18
+ end
19
+
20
+ context("for SQLite") do
21
+ before(:each) do
22
+ @visitor = Arel::Visitors::SQLite.new(Arel::Sql::Engine.new(FakeRecord::Base.new('sqlite')))
23
+ end
24
+
25
+ it "should correctly transform to_sql DATE, MONTH, DAYOFMONTH" do
26
+ @visitor.accept(@table[:created_at].year.eq(2009)).should eq('CAST(STRFTIME(\'%Y\', "users"."created_at") AS INTEGER) = 2009')
27
+ @visitor.accept(@table[:created_at].month.in(1..12)).should eq('CAST(STRFTIME(\'%m\', "users"."created_at") AS INTEGER) BETWEEN 1 AND 12')
28
+ @visitor.accept(@table[:created_at].dayofmonth.gt(10)).should eq('CAST(STRFTIME(\'%d\', "users"."created_at") AS INTEGER) > 10')
29
+ @table.project(@table[:created_at].year).group(@table[:created_at].year).to_sql.should
30
+ eq('SELECT CAST(STRFTIME(\'%Y\', "users"."created_at") AS INTEGER) FROM "users" GROUP BY CAST(STRFTIME(\'%Y\', "users"."created_at") AS INTEGER)')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe "date_scopes AR specs" do
4
+ before(:each) do
5
+ User.destroy_all
6
+ @users = [
7
+ User.create(:created_at => Date.new(2009, 1, 29)),
8
+ User.create(:created_at => Date.new(2008, 1, 1))
9
+ ]
10
+ end
11
+
12
+ it "have working *_eq" do
13
+ @by_year = User.created_at_year_eq(2009)
14
+ @by_year.count.should == 1
15
+ @by_year.first.should == @users.first
16
+
17
+ @by_month = User.created_at_month_eq(1)
18
+ @by_month.count.should == 2
19
+ @by_month.should include(@users.first)
20
+ @by_month.should include(@users.second)
21
+
22
+ @by_month = User.created_at_day_eq(29)
23
+ @by_month.count.should == 1
24
+ @by_month.first.should == @users.first
25
+ end
26
+
27
+ it "have working *_years/*_months scopes" do
28
+ @years = User.order('created_at DESC').created_at_years.all
29
+ @years.count.should == 2
30
+ @years.first['created_at_year'].should == 2009
31
+ @years.last['created_at_year'].should == 2008
32
+
33
+ @months = User.order('created_at DESC').created_at_years.created_at_months.all
34
+ @months.count.should == 2
35
+ @months.first['created_at_month'].should == 1
36
+ @months.last['created_at_month'].should == 1
37
+
38
+ @days = User.order('created_at DESC').created_at_days.all
39
+ @days.count.should == 2
40
+ @days.first['created_at_day'].should == 29
41
+ @days.last['created_at_day'].should == 1
42
+ end
43
+
44
+ it "have working ascend_*/descend_* scopes" do
45
+ User.ascend_by_created_at.all.should eq(@users.reverse)
46
+ User.descend_by_created_at.all.should eq(@users)
47
+ end
48
+
49
+ it "gets column value with all_column" do
50
+ User.ascend_by_created_at.created_at_years.all_column.should == [2008, 2009]
51
+ end
52
+ end
@@ -0,0 +1,37 @@
1
+ $LOAD_PATH << "." unless $LOAD_PATH.include?(".")
2
+
3
+ require 'logger'
4
+ require "bundler"
5
+
6
+ begin
7
+ Bundler.setup
8
+ Bundler.require
9
+ rescue Bundler::GemNotFound
10
+ raise RuntimeError, "Bundler couldn't find some gems." +
11
+ "Did you run `bundle install`?"
12
+ end
13
+
14
+ require 'active_record'
15
+ require 'support/fake_record'
16
+
17
+ # Fake connection to supress ConnectionNotEstablished on AR tests
18
+ ActiveRecord::Base.establish_connection(
19
+ "adapter" => "sqlite3",
20
+ "database" => ":memory:"
21
+ )
22
+
23
+ ActiveRecord::Base.logger = Logger.new(nil)
24
+ ActiveRecord::Base.send(:include, ArelDateScopes::ActiveRecord)
25
+
26
+ ActiveRecord::Schema.define :version => 0 do
27
+ create_table "users", :force => true do |t|
28
+ t.datetime :created_at
29
+ end
30
+ end
31
+
32
+ class User < ActiveRecord::Base
33
+ set_table_name 'users'
34
+ date_scopes_for :created_at
35
+ end
36
+
37
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
@@ -0,0 +1,90 @@
1
+ # Mock to make AREL work without regular database.
2
+ module FakeRecord
3
+ class Column < Struct.new(:name, :type)
4
+ end
5
+
6
+ class Connection
7
+ attr_reader :tables
8
+
9
+ def initialize
10
+ @tables = %w{ users }
11
+ @columns = {
12
+ 'users' => [
13
+ Column.new('id', :integer),
14
+ Column.new('created_at', :date)
15
+ ]
16
+ }
17
+ @primary_keys = {
18
+ 'users' => 'id'
19
+ }
20
+ end
21
+
22
+ def primary_key name
23
+ @primary_keys[name.to_s]
24
+ end
25
+
26
+ def table_exists? name
27
+ @tables.include? name.to_s
28
+ end
29
+
30
+ def columns name, message = nil
31
+ @columns[name.to_s]
32
+ end
33
+
34
+ def quote_table_name name
35
+ "\"#{name.to_s}\""
36
+ end
37
+
38
+ def quote_column_name name
39
+ "\"#{name.to_s}\""
40
+ end
41
+
42
+ def quote thing, column = nil
43
+ if column && column.type == :integer
44
+ return 'NULL' if thing.nil?
45
+ return thing.to_i
46
+ end
47
+
48
+ case thing
49
+ when true
50
+ "'t'"
51
+ when false
52
+ "'f'"
53
+ when nil
54
+ 'NULL'
55
+ when Numeric
56
+ thing
57
+ else
58
+ "'#{thing}'"
59
+ end
60
+ end
61
+ end
62
+
63
+ class ConnectionPool
64
+ class Spec < Struct.new(:config)
65
+ end
66
+
67
+ attr_reader :spec, :connection
68
+
69
+ def initialize(adapter)
70
+ @spec = Spec.new(adapter)
71
+ @connection = Connection.new
72
+ end
73
+
74
+ def with_connection
75
+ yield connection
76
+ end
77
+ end
78
+
79
+ class Base
80
+ attr_accessor :connection_pool
81
+
82
+ def initialize(adapter)
83
+ @connection_pool = ConnectionPool.new(adapter)
84
+ end
85
+
86
+ def connection
87
+ connection_pool.connection
88
+ end
89
+ end
90
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arel_date_scopes
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Victor Sokolov
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-30 00:00:00 +04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: arel
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 2
32
+ version: "2"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: activerecord
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 7
44
+ segments:
45
+ - 3
46
+ - 0
47
+ - 0
48
+ version: 3.0.0
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: activesupport
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 7
60
+ segments:
61
+ - 3
62
+ - 0
63
+ - 0
64
+ version: 3.0.0
65
+ type: :runtime
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: sqlite3-ruby
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ type: :development
94
+ version_requirements: *id005
95
+ description: SQL date functions for AREL 2 + AR 3 scopes (such as created_at_year_eq)
96
+ email: gzigzigzeo@gmail.com
97
+ executables: []
98
+
99
+ extensions: []
100
+
101
+ extra_rdoc_files: []
102
+
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - Gemfile
107
+ - Gemfile.lock
108
+ - README.rdoc
109
+ - Rakefile
110
+ - arel_date_scopes.gemspec
111
+ - lib/arel_date_scopes.rb
112
+ - lib/arel_date_scopes/active_record.rb
113
+ - lib/arel_date_scopes/arel.rb
114
+ - lib/arel_date_scopes/railtie.rb
115
+ - lib/arel_date_scopes/version.rb
116
+ - spec/arel_date_scopes/date_scopes_arel_spec.rb
117
+ - spec/arel_date_scopes/date_scopes_spec.rb
118
+ - spec/spec_helper.rb
119
+ - spec/support/fake_record.rb
120
+ has_rdoc: true
121
+ homepage: http://github.com/gzigzigzeo/arel_date_scopes
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options:
126
+ - --charset=UTF-8
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ hash: 3
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ hash: 3
144
+ segments:
145
+ - 0
146
+ version: "0"
147
+ requirements: []
148
+
149
+ rubyforge_project:
150
+ rubygems_version: 1.6.0
151
+ signing_key:
152
+ specification_version: 3
153
+ summary: SQL date functions for AREL 2 + AR 3 date scopes (such as created_at_year_eq)
154
+ test_files:
155
+ - spec/arel_date_scopes/date_scopes_arel_spec.rb
156
+ - spec/arel_date_scopes/date_scopes_spec.rb
157
+ - spec/spec_helper.rb
158
+ - spec/support/fake_record.rb