somehow_has_relation 0.0.1

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.
Files changed (120) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +12 -0
  3. data/Rakefile +23 -0
  4. data/lib/somehow_has_relation/version.rb +3 -0
  5. data/lib/somehow_has_relation.rb +68 -0
  6. data/somehow_has_relation.gemspec +24 -0
  7. data/test/dummy2/README +243 -0
  8. data/test/dummy2/Rakefile +10 -0
  9. data/test/dummy2/app/controllers/application_controller.rb +10 -0
  10. data/test/dummy2/app/helpers/application_helper.rb +3 -0
  11. data/test/dummy2/app/models/author.rb +4 -0
  12. data/test/dummy2/app/models/bio.rb +4 -0
  13. data/test/dummy2/app/models/comment.rb +8 -0
  14. data/test/dummy2/app/models/post.rb +4 -0
  15. data/test/dummy2/config/boot.rb +115 -0
  16. data/test/dummy2/config/database.yml +22 -0
  17. data/test/dummy2/config/environment.rb +43 -0
  18. data/test/dummy2/config/environments/development.rb +17 -0
  19. data/test/dummy2/config/environments/production.rb +28 -0
  20. data/test/dummy2/config/environments/test.rb +28 -0
  21. data/test/dummy2/config/initializers/backtrace_silencers.rb +7 -0
  22. data/test/dummy2/config/initializers/cookie_verification_secret.rb +7 -0
  23. data/test/dummy2/config/initializers/inflections.rb +10 -0
  24. data/test/dummy2/config/initializers/mime_types.rb +5 -0
  25. data/test/dummy2/config/initializers/new_rails_defaults.rb +21 -0
  26. data/test/dummy2/config/initializers/session_store.rb +15 -0
  27. data/test/dummy2/config/locales/en.yml +5 -0
  28. data/test/dummy2/config/routes.rb +43 -0
  29. data/test/dummy2/db/development.sqlite3 +0 -0
  30. data/test/dummy2/db/migrate/20110316130454_create_posts.rb +12 -0
  31. data/test/dummy2/db/migrate/20110316142731_create_authors.rb +13 -0
  32. data/test/dummy2/db/migrate/20110316144725_create_comments.rb +13 -0
  33. data/test/dummy2/db/migrate/20110316154717_remove_post_id_from_author.rb +9 -0
  34. data/test/dummy2/db/migrate/20110316154912_add_author_id_to_post.rb +9 -0
  35. data/test/dummy2/db/migrate/20110316155523_create_bios.rb +13 -0
  36. data/test/dummy2/db/migrate/20110316155643_add_bio_id_to_comment.rb +9 -0
  37. data/test/dummy2/db/seeds.rb +7 -0
  38. data/test/dummy2/db/test.sqlite3 +0 -0
  39. data/test/dummy2/log/development.log +52 -0
  40. data/test/dummy2/log/production.log +0 -0
  41. data/test/dummy2/log/server.log +0 -0
  42. data/test/dummy2/log/test.log +11438 -0
  43. data/test/dummy2/public/404.html +30 -0
  44. data/test/dummy2/public/422.html +30 -0
  45. data/test/dummy2/public/500.html +30 -0
  46. data/test/dummy2/public/favicon.ico +0 -0
  47. data/test/dummy2/public/images/rails.png +0 -0
  48. data/test/dummy2/public/index.html +275 -0
  49. data/test/dummy2/public/javascripts/application.js +2 -0
  50. data/test/dummy2/public/javascripts/controls.js +963 -0
  51. data/test/dummy2/public/javascripts/dragdrop.js +973 -0
  52. data/test/dummy2/public/javascripts/effects.js +1128 -0
  53. data/test/dummy2/public/javascripts/prototype.js +4320 -0
  54. data/test/dummy2/public/robots.txt +5 -0
  55. data/test/dummy2/script/about +4 -0
  56. data/test/dummy2/script/console +3 -0
  57. data/test/dummy2/script/dbconsole +3 -0
  58. data/test/dummy2/script/destroy +3 -0
  59. data/test/dummy2/script/generate +3 -0
  60. data/test/dummy2/script/performance/benchmarker +3 -0
  61. data/test/dummy2/script/performance/profiler +3 -0
  62. data/test/dummy2/script/plugin +3 -0
  63. data/test/dummy2/script/runner +3 -0
  64. data/test/dummy2/script/server +3 -0
  65. data/test/dummy2/test/fixtures/authors.yml +7 -0
  66. data/test/dummy2/test/fixtures/bios.yml +7 -0
  67. data/test/dummy2/test/fixtures/comments.yml +7 -0
  68. data/test/dummy2/test/fixtures/posts.yml +11 -0
  69. data/test/dummy2/test/unit/author_test.rb +8 -0
  70. data/test/dummy2/test/unit/bio_test.rb +8 -0
  71. data/test/dummy2/test/unit/comment_test.rb +8 -0
  72. data/test/dummy2/test/unit/post_test.rb +8 -0
  73. data/test/dummy3/.gitignore +4 -0
  74. data/test/dummy3/Rakefile +7 -0
  75. data/test/dummy3/app/controllers/application_controller.rb +3 -0
  76. data/test/dummy3/app/helpers/application_helper.rb +2 -0
  77. data/test/dummy3/app/models/author.rb +4 -0
  78. data/test/dummy3/app/models/bio.rb +4 -0
  79. data/test/dummy3/app/models/comment.rb +8 -0
  80. data/test/dummy3/app/models/post.rb +4 -0
  81. data/test/dummy3/app/views/layouts/application.html.erb +14 -0
  82. data/test/dummy3/config/application.rb +40 -0
  83. data/test/dummy3/config/boot.rb +8 -0
  84. data/test/dummy3/config/database.yml +22 -0
  85. data/test/dummy3/config/environment.rb +5 -0
  86. data/test/dummy3/config/environments/development.rb +26 -0
  87. data/test/dummy3/config/environments/production.rb +49 -0
  88. data/test/dummy3/config/environments/test.rb +35 -0
  89. data/test/dummy3/config/initializers/backtrace_silencers.rb +7 -0
  90. data/test/dummy3/config/initializers/inflections.rb +10 -0
  91. data/test/dummy3/config/initializers/mime_types.rb +5 -0
  92. data/test/dummy3/config/initializers/secret_token.rb +7 -0
  93. data/test/dummy3/config/initializers/session_store.rb +8 -0
  94. data/test/dummy3/config/locales/en.yml +5 -0
  95. data/test/dummy3/config/routes.rb +58 -0
  96. data/test/dummy3/config.ru +4 -0
  97. data/test/dummy3/db/migrate/20110317224541_create_posts.rb +13 -0
  98. data/test/dummy3/db/migrate/20110317224616_create_bios.rb +13 -0
  99. data/test/dummy3/db/migrate/20110317224637_create_comments.rb +14 -0
  100. data/test/dummy3/db/migrate/20110317230301_create_authors.rb +12 -0
  101. data/test/dummy3/db/seeds.rb +7 -0
  102. data/test/dummy3/lib/tasks/.gitkeep +0 -0
  103. data/test/dummy3/public/404.html +26 -0
  104. data/test/dummy3/public/422.html +26 -0
  105. data/test/dummy3/public/500.html +26 -0
  106. data/test/dummy3/public/favicon.ico +0 -0
  107. data/test/dummy3/public/images/rails.png +0 -0
  108. data/test/dummy3/public/index.html +239 -0
  109. data/test/dummy3/public/javascripts/application.js +2 -0
  110. data/test/dummy3/public/javascripts/controls.js +965 -0
  111. data/test/dummy3/public/javascripts/dragdrop.js +974 -0
  112. data/test/dummy3/public/javascripts/effects.js +1123 -0
  113. data/test/dummy3/public/javascripts/prototype.js +6001 -0
  114. data/test/dummy3/public/javascripts/rails.js +191 -0
  115. data/test/dummy3/public/robots.txt +5 -0
  116. data/test/dummy3/public/stylesheets/.gitkeep +0 -0
  117. data/test/dummy3/script/rails +6 -0
  118. data/test/somehow_has_relation_test.rb +114 -0
  119. data/test/test_helper.rb +27 -0
  120. metadata +187 -0
@@ -0,0 +1,191 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+
176
+ Ajax.Responders.register({
177
+ onCreate: function(request) {
178
+ var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
179
+
180
+ if (csrf_meta_tag) {
181
+ var header = 'X-CSRF-Token',
182
+ token = csrf_meta_tag.readAttribute('content');
183
+
184
+ if (!request.options.requestHeaders) {
185
+ request.options.requestHeaders = {};
186
+ }
187
+ request.options.requestHeaders[header] = token;
188
+ }
189
+ }
190
+ });
191
+ })();
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,114 @@
1
+ require 'test_helper'
2
+
3
+ class SomehowHasRelationTest < ActiveSupport::TestCase
4
+ setup do
5
+ Post.somehow_has
6
+ end
7
+
8
+ test "somehow_has_relation is a Module" do
9
+ assert_kind_of Module, SomehowHasRelation
10
+ end
11
+
12
+ test "ActiveRecord::Base should have a somehow_has method" do
13
+ assert ActiveRecord::Base.methods.include? :somehow_has.to_s
14
+ end
15
+
16
+ test "when somehow_has is called, it should define SOMEHOW_HAS_RELATION" do
17
+ assert Post.const_defined?('SOMEHOW_HAS_RELATION')
18
+ end
19
+
20
+ test "an Hash of parameters should be passed to somehow_has" do
21
+ assert_equal Hash, Post::SOMEHOW_HAS_RELATION.class
22
+ end
23
+
24
+ test "reinitialize when somehow_has is called more than once" do
25
+ params = {:newparam => 'newvalue'}
26
+ Post.somehow_has params
27
+ assert_equal params, Post::SOMEHOW_HAS_RELATION
28
+ end
29
+
30
+ test "relations should work even when somehow_has has not been defined for first step" do
31
+ @post = Post.create(:author => Author.create, :comments => [Comment.create, Comment.create])
32
+
33
+ assert_equal @post.author, @post.related_author
34
+ assert_equal @post.comments, @post.related_comments
35
+ end
36
+
37
+ test "1-step relation defines a method prefixed with related_ for standard associations methods" do
38
+ @post = Post.create(:author => Author.create, :comments => [Comment.create, Comment.create])
39
+
40
+ Post.somehow_has :one => :author
41
+ assert_equal @post.author, @post.related_author
42
+
43
+ Post.somehow_has :many => :comments
44
+ assert_equal @post.comments, @post.related_comments
45
+ end
46
+
47
+ test "1-step relations also looks for belongs_to associations (with :has_one)" do
48
+ @bio = Bio.create(:author => Author.create)
49
+
50
+ Bio.somehow_has :one => :author
51
+ assert_equal @bio.author, @bio.related_author
52
+ end
53
+
54
+ test "2-steps relations use :through and define a related_ prefixed method named as the last association" do
55
+ comments = [Comment.create, Comment.create]
56
+ @author = Author.create(:bio => Bio.create(:comments => comments))
57
+
58
+ Author.somehow_has :many => :comments, :through => :bio
59
+ assert_equal comments, @author.related_comments
60
+ end
61
+
62
+ test "2-steps relations should return an array of arrays when there are nested has_many associations" do
63
+ comments1, comments2 = [Comment.create, Comment.create], [Comment.create, Comment.create]
64
+ posts = [Post.create(:comments => comments1), Post.create(:comments => comments2)]
65
+ @author = Author.create(:posts => posts)
66
+
67
+ Post.somehow_has :many => :comments
68
+ Author.somehow_has :many => :comments, :through => :posts
69
+ assert_equal [comments1, comments2].flatten, @author.related_comments
70
+ end
71
+
72
+ test "3-steps relations should work just like 2-steps and n-steps relations" do
73
+ comments1, comments2 = [Comment.create, Comment.create], [Comment.create, Comment.create]
74
+ posts = [Post.create(:comments => comments1), Post.create(:comments => comments2)]
75
+ author = Author.create(:posts => posts)
76
+ @bio = Bio.create(:author => author)
77
+
78
+ Post.somehow_has :many => :comments
79
+ Author.somehow_has :many => :comments, :through => :posts
80
+ Bio.somehow_has :many => :comments, :through => :author
81
+ assert_equal [comments1, comments2].flatten, @bio.related_comments
82
+ end
83
+
84
+ test "somehow_has takes an :if argument which specifies a Proc to check against relations" do
85
+ new_comment, old_comment = Comment.create, Comment.create
86
+ old_comment.update_attribute :created_at, 1.day.ago
87
+ recent_comments = Proc.new{|comment| comment.created_at >= 1.hour.ago }
88
+ @author = Author.create(:posts => [Post.create(:comments => [new_comment, old_comment])])
89
+
90
+ Author.somehow_has :many => :comments, :through => :posts, :if => recent_comments
91
+ assert_equal [new_comment], @author.related_comments
92
+ end
93
+
94
+ test "somehow_has takes an :if argument which specifies a Symbol for a method that returns a boolean to check against relations" do
95
+ new_comment, old_comment = Comment.create, Comment.create
96
+ old_comment.update_attribute :created_at, 1.day.ago
97
+ @author = Author.create(:posts => [Post.create(:comments => [new_comment, old_comment])])
98
+
99
+ Author.somehow_has :many => :comments, :through => :posts, :if => :recent?
100
+ assert_equal [new_comment], @author.related_comments
101
+ end
102
+
103
+ test "somehow_has takes an :as argument which overloads the defined related_%{relation_name} method name" do
104
+ Post.somehow_has :many => :comments, :as => :blabla
105
+ assert Post.instance_methods.include? :blabla.to_s
106
+ end
107
+
108
+ test ":if argument should also work for somehow_has :one" do
109
+ @bio = Bio.create(:author => Author.create)
110
+
111
+ Bio.somehow_has :one => :author, :if => Proc.new{|author| author.created_at <= 10.years.ago}
112
+ assert_nil @bio.related_author
113
+ end
114
+ end
@@ -0,0 +1,27 @@
1
+ # Configure Rails Envinronment
2
+ ENV["RAILS_ENV"] = "test"
3
+ ENV["RAILS_VER"] ||= "2"
4
+
5
+ require "somehow_has_relation"
6
+
7
+ require File.expand_path("../dummy#{ENV["RAILS_VER"]}/config/environment.rb", __FILE__)
8
+
9
+ if ENV["RAILS_VER"] == "2"
10
+ require "test_help"
11
+ else
12
+ require "rails/test_help"
13
+ end
14
+
15
+ require 'redgreen'
16
+
17
+ ActionMailer::Base.delivery_method = :test
18
+ ActionMailer::Base.perform_deliveries = true
19
+ ActionMailer::Base.default_url_options[:host] = "test.com"
20
+
21
+ Rails.backtrace_cleaner.remove_silencers!
22
+
23
+ # Run any available migration
24
+ ActiveRecord::Migrator.migrate File.expand_path("../dummy#{ENV["RAILS_VER"]}/db/migrate/", __FILE__)
25
+
26
+ # Load support files
27
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: somehow_has_relation
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Matteo Latini
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-18 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: simple recursive activerecord relations for rails2 and rails3
23
+ email:
24
+ - mtylty@gmail.com
25
+ - m.latini@caspur.it
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - Rakefile
36
+ - lib/somehow_has_relation.rb
37
+ - lib/somehow_has_relation/version.rb
38
+ - somehow_has_relation.gemspec
39
+ - test/dummy2/README
40
+ - test/dummy2/Rakefile
41
+ - test/dummy2/app/controllers/application_controller.rb
42
+ - test/dummy2/app/helpers/application_helper.rb
43
+ - test/dummy2/app/models/author.rb
44
+ - test/dummy2/app/models/bio.rb
45
+ - test/dummy2/app/models/comment.rb
46
+ - test/dummy2/app/models/post.rb
47
+ - test/dummy2/config/boot.rb
48
+ - test/dummy2/config/database.yml
49
+ - test/dummy2/config/environment.rb
50
+ - test/dummy2/config/environments/development.rb
51
+ - test/dummy2/config/environments/production.rb
52
+ - test/dummy2/config/environments/test.rb
53
+ - test/dummy2/config/initializers/backtrace_silencers.rb
54
+ - test/dummy2/config/initializers/cookie_verification_secret.rb
55
+ - test/dummy2/config/initializers/inflections.rb
56
+ - test/dummy2/config/initializers/mime_types.rb
57
+ - test/dummy2/config/initializers/new_rails_defaults.rb
58
+ - test/dummy2/config/initializers/session_store.rb
59
+ - test/dummy2/config/locales/en.yml
60
+ - test/dummy2/config/routes.rb
61
+ - test/dummy2/db/development.sqlite3
62
+ - test/dummy2/db/migrate/20110316130454_create_posts.rb
63
+ - test/dummy2/db/migrate/20110316142731_create_authors.rb
64
+ - test/dummy2/db/migrate/20110316144725_create_comments.rb
65
+ - test/dummy2/db/migrate/20110316154717_remove_post_id_from_author.rb
66
+ - test/dummy2/db/migrate/20110316154912_add_author_id_to_post.rb
67
+ - test/dummy2/db/migrate/20110316155523_create_bios.rb
68
+ - test/dummy2/db/migrate/20110316155643_add_bio_id_to_comment.rb
69
+ - test/dummy2/db/seeds.rb
70
+ - test/dummy2/db/test.sqlite3
71
+ - test/dummy2/log/development.log
72
+ - test/dummy2/log/production.log
73
+ - test/dummy2/log/server.log
74
+ - test/dummy2/log/test.log
75
+ - test/dummy2/public/404.html
76
+ - test/dummy2/public/422.html
77
+ - test/dummy2/public/500.html
78
+ - test/dummy2/public/favicon.ico
79
+ - test/dummy2/public/images/rails.png
80
+ - test/dummy2/public/index.html
81
+ - test/dummy2/public/javascripts/application.js
82
+ - test/dummy2/public/javascripts/controls.js
83
+ - test/dummy2/public/javascripts/dragdrop.js
84
+ - test/dummy2/public/javascripts/effects.js
85
+ - test/dummy2/public/javascripts/prototype.js
86
+ - test/dummy2/public/robots.txt
87
+ - test/dummy2/script/about
88
+ - test/dummy2/script/console
89
+ - test/dummy2/script/dbconsole
90
+ - test/dummy2/script/destroy
91
+ - test/dummy2/script/generate
92
+ - test/dummy2/script/performance/benchmarker
93
+ - test/dummy2/script/performance/profiler
94
+ - test/dummy2/script/plugin
95
+ - test/dummy2/script/runner
96
+ - test/dummy2/script/server
97
+ - test/dummy2/test/fixtures/authors.yml
98
+ - test/dummy2/test/fixtures/bios.yml
99
+ - test/dummy2/test/fixtures/comments.yml
100
+ - test/dummy2/test/fixtures/posts.yml
101
+ - test/dummy2/test/unit/author_test.rb
102
+ - test/dummy2/test/unit/bio_test.rb
103
+ - test/dummy2/test/unit/comment_test.rb
104
+ - test/dummy2/test/unit/post_test.rb
105
+ - test/dummy3/.gitignore
106
+ - test/dummy3/Rakefile
107
+ - test/dummy3/app/controllers/application_controller.rb
108
+ - test/dummy3/app/helpers/application_helper.rb
109
+ - test/dummy3/app/models/author.rb
110
+ - test/dummy3/app/models/bio.rb
111
+ - test/dummy3/app/models/comment.rb
112
+ - test/dummy3/app/models/post.rb
113
+ - test/dummy3/app/views/layouts/application.html.erb
114
+ - test/dummy3/config.ru
115
+ - test/dummy3/config/application.rb
116
+ - test/dummy3/config/boot.rb
117
+ - test/dummy3/config/database.yml
118
+ - test/dummy3/config/environment.rb
119
+ - test/dummy3/config/environments/development.rb
120
+ - test/dummy3/config/environments/production.rb
121
+ - test/dummy3/config/environments/test.rb
122
+ - test/dummy3/config/initializers/backtrace_silencers.rb
123
+ - test/dummy3/config/initializers/inflections.rb
124
+ - test/dummy3/config/initializers/mime_types.rb
125
+ - test/dummy3/config/initializers/secret_token.rb
126
+ - test/dummy3/config/initializers/session_store.rb
127
+ - test/dummy3/config/locales/en.yml
128
+ - test/dummy3/config/routes.rb
129
+ - test/dummy3/db/migrate/20110317224541_create_posts.rb
130
+ - test/dummy3/db/migrate/20110317224616_create_bios.rb
131
+ - test/dummy3/db/migrate/20110317224637_create_comments.rb
132
+ - test/dummy3/db/migrate/20110317230301_create_authors.rb
133
+ - test/dummy3/db/seeds.rb
134
+ - test/dummy3/lib/tasks/.gitkeep
135
+ - test/dummy3/public/404.html
136
+ - test/dummy3/public/422.html
137
+ - test/dummy3/public/500.html
138
+ - test/dummy3/public/favicon.ico
139
+ - test/dummy3/public/images/rails.png
140
+ - test/dummy3/public/index.html
141
+ - test/dummy3/public/javascripts/application.js
142
+ - test/dummy3/public/javascripts/controls.js
143
+ - test/dummy3/public/javascripts/dragdrop.js
144
+ - test/dummy3/public/javascripts/effects.js
145
+ - test/dummy3/public/javascripts/prototype.js
146
+ - test/dummy3/public/javascripts/rails.js
147
+ - test/dummy3/public/robots.txt
148
+ - test/dummy3/public/stylesheets/.gitkeep
149
+ - test/dummy3/script/rails
150
+ - test/somehow_has_relation_test.rb
151
+ - test/test_helper.rb
152
+ has_rdoc: true
153
+ homepage: https://github.com/mtylty/somehow_has_relation
154
+ licenses: []
155
+
156
+ post_install_message:
157
+ rdoc_options: []
158
+
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ hash: 3
167
+ segments:
168
+ - 0
169
+ version: "0"
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ hash: 3
176
+ segments:
177
+ - 0
178
+ version: "0"
179
+ requirements: []
180
+
181
+ rubyforge_project: somehow_has_relation
182
+ rubygems_version: 1.5.3
183
+ signing_key:
184
+ specification_version: 3
185
+ summary: somehow_has_relation is a tiny gem that makes it easy to traverse multiple ActiveRecord associations by defining a somehow_has method. When somehow_has is defined on multiple models, the gem will try to look recursively to find other models on which somehow_has has been defined.
186
+ test_files: []
187
+