hobo 2.0.1 → 2.1.0.pre1

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 (32) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES-2.1.markdown +57 -0
  3. data/Gemfile +1 -1
  4. data/VERSION +1 -1
  5. data/app/helpers/hobo_permissions_helper.rb +1 -1
  6. data/app/helpers/hobo_route_helper.rb +10 -79
  7. data/config/routes.rb +2 -2
  8. data/hobo.gemspec +1 -1
  9. data/lib/generators/hobo/admin_subsite/admin_subsite_generator.rb +3 -1
  10. data/lib/generators/hobo/controller.rb +4 -1
  11. data/lib/generators/hobo/front_controller/front_controller_generator.rb +7 -6
  12. data/lib/generators/hobo/i18n/templates/hobo.en.yml +2 -1
  13. data/lib/generators/hobo/i18n/templates/hobo.es.yml +1 -0
  14. data/lib/generators/hobo/i18n/templates/hobo.ru.yml +1 -0
  15. data/lib/generators/hobo/routes/router.rb +5 -3
  16. data/lib/generators/hobo/routes/templates/hobo_routes.rb.erb +0 -36
  17. data/lib/generators/hobo/setup_wizard/setup_wizard_generator.rb +2 -2
  18. data/lib/hobo.rb +2 -2
  19. data/lib/hobo/controller.rb +1 -1
  20. data/lib/hobo/controller/model.rb +4 -4
  21. data/lib/hobo/extensions/active_record/associations/association.rb +1 -1
  22. data/lib/hobo/extensions/active_record/associations/scope.rb +6 -5
  23. data/lib/hobo/extensions/active_record/relation_with_origin.rb +9 -7
  24. data/lib/hobo/model.rb +1 -2
  25. data/lib/hobo/model/accessible_associations.rb +4 -5
  26. data/lib/hobo/model/permissions.rb +7 -6
  27. data/lib/hobo/model/scopes.rb +1 -3
  28. data/lib/hobo/model/scopes/apply_scopes.rb +3 -3
  29. data/test/irt/generators/admin_subsite.irt +6 -0
  30. metadata +17 -39
  31. data/test/doctest/hobo/multi_model_forms.rdoctest +0 -260
  32. data/test/doctest/hobo/scopes.rdoctest +0 -375
@@ -1,375 +0,0 @@
1
- Hobo Scopes
2
- {: .document-title}
3
-
4
- doctest: prepare testapp environment
5
- doctest_require: '../prepare_testapp'
6
- {.hidden}
7
-
8
- Hobo scopes are an extension of the *named scope* and *dynamic finder*
9
- functionality introduced in Rails 2.1, 2.2 and 2.3.
10
-
11
- Most of these scopes work by calling `named_scope` the first time they
12
- are invoked. They should work at the same speed as a named scope on
13
- subsequent invocations.
14
-
15
- However, this does substantially slow down `method_missing` on your
16
- model's class. If `ActiveRecord::Base.method_missing` is used often,
17
- you may wish to disable this module. (FIXME: how to do that)
18
-
19
- Contents
20
- {: .contents-heading}
21
-
22
- - contents
23
- {:toc}
24
-
25
- This document was created using the tool
26
- [rubydoctest](http://github.com/tablatom/rubydoctest). This means
27
- that this file serves as both documentation and test. As a side
28
- effect, it also ensures that errors do not creep into the sample code
29
- in this documentation.
30
- {.hidden}
31
-
32
- The idea behind rubydoctest is that you should be able to recreate
33
- everything in this document from an irb console. It is recommended
34
- that you skip down to the [fixture definitions](#fixture_definition).
35
- Nobody but the computer needs to read the rest of this section.
36
- {.hidden}
37
-
38
- Let's set up a few models for our testing:
39
-
40
- >> File.open("#{Rails.root}/app/models/person.rb", "w") do |f|
41
- f.write("""
42
- class Person < ActiveRecord::Base
43
- hobo_model
44
-
45
- fields do
46
- name :string
47
- born_at :date
48
- code :integer
49
- male :boolean
50
- timestamps
51
- end
52
- attr_accessible :name, :born_at, :code, :male
53
-
54
- lifecycle(:key_timestamp_field => false) do
55
- state :inactive, :active
56
- end
57
-
58
- has_many :friendships
59
- has_many :friends, :through => :friendships
60
- end
61
- """)
62
- end
63
- >> File.open("#{Rails.root}/app/models/friendship.rb", "w") do |f|
64
- f.write("""
65
- class Friendship < ActiveRecord::Base
66
- hobo_model
67
- fields
68
- attr_accessible :person, :friend
69
- belongs_to :person
70
- belongs_to :friend, :class_name => 'Person'
71
- end
72
- """)
73
- end
74
-
75
- Generate a migration and run it:
76
- {.hidden}
77
-
78
- >> system("rails g hobo:migration -m -n")
79
- >> ActionDispatch::Reloader.cleanup!
80
- >> ActionDispatch::Reloader.prepare!
81
- >> Person.connection.clear_cache!
82
- >> Person.connection.schema_cache.clear!
83
- >> Person.reset_column_information
84
- >> Person.columns.*.name
85
- => ["id", "name", "born_at", "code", "male", "created_at", "updated_at", "state"]
86
- {.hidden}
87
-
88
- And create a couple of fixtures:
89
-
90
- >>
91
- Bryan = Person.new(:name => "Bryan", :code => 17,
92
- :born_at => Date.new(1973,4,8), :male => true)
93
- >> Bryan.state = "active"
94
- >> Bryan.save!
95
- >>
96
- Bethany = Person.new(:name => "Bethany", :code => 42,
97
- :born_at => Date.new(1975,5,13), :male => false)
98
- >> Bethany.state = "inactive"
99
- >> Bethany.save!
100
- >> Friendship.new(:person => Bryan, :friend => Bethany).save!
101
-
102
- Hack the `created_at` column to get predictable sorting.
103
-
104
- >> Bethany.created_at = Date.new(2000)
105
- >> Bethany.save!
106
-
107
- We're ready to get going.
108
-
109
- # Simple Scopes
110
-
111
- ## \_is
112
-
113
- Most Hobo scopes work by appending an appropriate query string to the
114
- field name. In this case, the hobo scope function name is the name of
115
- your database column, followed by `_is`. It returns an Array of models.
116
-
117
- It works the same as a dynamic finder:
118
-
119
- >> Person.find_all_by_name("Bryan").*.name
120
- => ["Bryan"]
121
- >> Person.name_is("Bryan").*.name
122
- => ["Bryan"]
123
- >> Person.code_is(17).*.name
124
- => ["Bryan"]
125
- >> Person.code_is(99).length
126
- => 0
127
-
128
- ## \_is\_not
129
-
130
- But the Hobo scope form allows us to supply several variations
131
-
132
- >> Person.name_is_not("Bryan").*.name
133
- => ["Bethany"]
134
-
135
- ## \_contains
136
-
137
- Case insensitive.
138
-
139
- >> Person.name_contains("y").*.name
140
- => ["Bryan", "Bethany"]
141
-
142
- ## \_does\_not\_contain
143
-
144
- Case insensitive.
145
-
146
- >> Person.name_does_not_contain("b").*.name
147
- => []
148
-
149
- ## \_starts
150
-
151
- Case insensitive.
152
-
153
- >> Person.name_starts("b").*.name
154
- => ["Bryan", "Bethany"]
155
-
156
- ## \_does\_not\_start
157
-
158
- Case insensitive.
159
-
160
- >> Person.name_does_not_start("B").length
161
- => 0
162
-
163
- ## \_ends
164
-
165
- >> Person.name_ends("y").*.name
166
- => ["Bethany"]
167
-
168
- ## \_does\_not\_end
169
-
170
- >> Person.name_does_not_end("y").*.name
171
- => ["Bryan"]
172
-
173
- # Boolean scopes
174
-
175
- ## \_
176
-
177
- If you use the name of the column by itself, the column is of type
178
- boolean, and no function is already defined on the model class with
179
- the name, Hobo scopes adds a dynamic finder to return all records with
180
- the boolean column set to `true`
181
-
182
- >> Person.male.*.name
183
- => ["Bryan"]
184
-
185
- ## not\_
186
-
187
- You can also search for boolean records that are not `true`. This
188
- includes all records that are set to `false` or `NULL`.
189
-
190
- >> Person.not_male.*.name
191
- => ["Bethany"]
192
-
193
- # Date scopes
194
-
195
- Date scopes work only with columns that have a name ending in "_at".
196
- The "_at" is omitted when using these finders.
197
-
198
- ## \_before
199
-
200
- >> Person.born_before(Date.new(1974)).*.name
201
- => ["Bryan"]
202
-
203
- ## \_after
204
-
205
- >> Person.born_after(Date.new(1974)).*.name
206
- => ["Bethany"]
207
-
208
- ## \_between
209
-
210
- >> Person.born_between(Date.new(1974), Date.today).*.name
211
- => ["Bethany"]
212
-
213
- # Lifecycle scopes
214
-
215
- If you have a [lifecycle](/manual/lifecycles) defined, each state name
216
- can be used as a dynamic finder.
217
-
218
- >> Person.active.*.name
219
- => ["Bryan"]
220
-
221
- # Key scopes
222
-
223
- This isn't very useful:
224
-
225
- >> Person.is(Bryan).*.name
226
- => ["Bryan"]
227
-
228
- But this is:
229
-
230
- >> Person.is_not(Bryan).*.name
231
- => ["Bethany"]
232
-
233
- # Static scopes
234
-
235
- These scopes do not contain the column name.
236
-
237
- ## by\_most\_recent
238
-
239
- Sorting on the `created_at` column:
240
-
241
- >> Person.by_most_recent.*.name
242
- => ["Bryan", "Bethany"]
243
-
244
- ## recent
245
-
246
- Gives the N most recent items:
247
-
248
- >> Person.recent(1).*.name
249
- => ["Bryan"]
250
-
251
- ## limit
252
-
253
- >> Person.limit(1).*.name
254
- => ["Bryan"]
255
-
256
- ## order\_by
257
-
258
- >> Person.order_by(:code).*.name
259
- => ["Bryan", "Bethany"]
260
-
261
- ## include
262
-
263
- DEPRECATED: Automatic scope :include has been deprecated: use :includes instead.
264
-
265
- ## includes
266
-
267
- >> Person.search("B", :name).includes(:friends).*.name # test LH#839
268
- => ["Bryan", "Bethany"]
269
-
270
- >> Person.includes(:friends).*.name
271
- => ["Bryan", "Bethany"]
272
-
273
- ## search
274
-
275
- Search for text in the specified column(s).
276
-
277
- >> Person.search("B", :name).*.name
278
- => ["Bryan", "Bethany"]
279
-
280
- # Association Scopes
281
-
282
- ## with\_
283
-
284
- Find the records that contain the specified record in an association
285
-
286
- >> Person.with_friendship(Friendship.first).*.name
287
- => ["Bryan"]
288
- >> Person.with_friend(Bethany).*.name
289
- => ["Bryan"]
290
-
291
- You can also specify multiple records with the plural form
292
-
293
- >> Person.with_friends(Bethany, nil).*.name
294
- => ["Bryan"]
295
-
296
- ## any\_of\_
297
-
298
- This works on plural associations to find a model associated with any of the arguments
299
-
300
- >> Person.any_of_friends(Bethany, Bryan).*.name
301
- => ["Bryan"]
302
-
303
- ## without\_
304
-
305
- >> Person.without_friend(Bethany).*.name
306
- => ["Bethany"]
307
- >> Person.without_friends(Bethany, nil).*.name
308
- => ["Bethany"]
309
-
310
-
311
- ## \_is
312
-
313
- You can use \_is on a `:has_one` or a `:belongs_to` relationship:
314
-
315
- >> Friendship.person_is(Bryan).*.friend.*.name
316
- => ["Bethany"]
317
-
318
- ## \_is\_not
319
-
320
- >> Friendship.person_is_not(Bryan)
321
- => []
322
-
323
- # Scoping Associations
324
-
325
- When defining an association, you can add a scope:
326
-
327
- >>
328
- class Person
329
- has_many :active_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => :active
330
- has_many :inactive_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => :inactive
331
- end
332
-
333
- >> Bryan.inactive_friends.*.name
334
- => ["Bethany"]
335
- >> Bryan.active_friends.*.name
336
- => []
337
-
338
- or several scopes:
339
-
340
- >>
341
- class Person
342
- has_many :inactive_female_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => [:inactive, :not_male]
343
- has_many :active_female_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => [:active, :not_male]
344
- has_many :inactive_male_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => [:inactive, :male]
345
- end
346
-
347
- >> Bryan.inactive_female_friends.*.name
348
- => ["Bethany"]
349
- >> Bryan.active_female_friends.*.name
350
- => []
351
- >> Bryan.inactive_male_friends.*.name
352
- => []
353
-
354
- You can parameterize the scopes:
355
-
356
- >>
357
- class Person
358
- has_many :y_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => { :name_contains => 'y' }
359
- has_many :z_friends, :class_name => "Person", :through => :friendships, :source => :friend, :scope => { :name_contains => 'z' }
360
- end
361
-
362
- >> Bryan.y_friends.*.name
363
- => ["Bethany"]
364
- >> Bryan.z_friends.*.name
365
- => []
366
-
367
-
368
- # Chaining
369
-
370
- Like named scopes, Hobo scopes can be chained:
371
-
372
- >> Bryan.inactive_friends.inactive.*.name
373
- => ["Bethany"]
374
-
375
- {.hidden}