hobo 0.5.3 → 0.6

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 (80) hide show
  1. data/bin/hobo +18 -4
  2. data/hobo_files/plugin/CHANGES.txt +511 -0
  3. data/hobo_files/plugin/README +8 -3
  4. data/hobo_files/plugin/Rakefile +81 -0
  5. data/hobo_files/plugin/generators/hobo/hobo_generator.rb +4 -4
  6. data/hobo_files/plugin/generators/hobo/templates/guest.rb +1 -1
  7. data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
  8. data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +16 -22
  9. data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +4 -6
  10. data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +6 -5
  11. data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +4 -6
  12. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +237 -0
  13. data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +9 -0
  14. data/hobo_files/plugin/generators/hobo_model/USAGE +2 -3
  15. data/hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb +1 -14
  16. data/hobo_files/plugin/generators/hobo_model/templates/fixtures.yml +1 -6
  17. data/hobo_files/plugin/generators/hobo_model/templates/model.rb +10 -4
  18. data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +7 -6
  19. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_base.css +68 -0
  20. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.css +93 -0
  21. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +11 -6
  22. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/plus.png +0 -0
  23. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +24 -14
  24. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +28 -44
  25. data/hobo_files/plugin/generators/hobo_user_model/USAGE +2 -12
  26. data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +1 -14
  27. data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +0 -6
  28. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +8 -1
  29. data/hobo_files/plugin/init.rb +6 -2
  30. data/hobo_files/plugin/lib/active_record/has_many_association.rb +23 -12
  31. data/hobo_files/plugin/lib/extensions.rb +134 -40
  32. data/hobo_files/plugin/lib/extensions/test_case.rb +0 -1
  33. data/hobo_files/plugin/lib/hobo.rb +77 -46
  34. data/hobo_files/plugin/lib/hobo/authenticated_user.rb +24 -2
  35. data/hobo_files/plugin/lib/hobo/authentication_support.rb +2 -1
  36. data/hobo_files/plugin/lib/hobo/controller.rb +35 -12
  37. data/hobo_files/plugin/lib/hobo/define_tags.rb +4 -4
  38. data/hobo_files/plugin/lib/hobo/dryml.rb +33 -51
  39. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +47 -34
  40. data/hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb +37 -0
  41. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +27 -5
  42. data/hobo_files/plugin/lib/hobo/dryml/template.rb +545 -302
  43. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +305 -135
  44. data/hobo_files/plugin/lib/hobo/email_address.rb +5 -0
  45. data/hobo_files/plugin/lib/hobo/field_spec.rb +66 -0
  46. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +325 -0
  47. data/hobo_files/plugin/lib/hobo/html_string.rb +2 -0
  48. data/hobo_files/plugin/lib/hobo/lazy_hash.rb +13 -1
  49. data/hobo_files/plugin/lib/hobo/markdown_string.rb +3 -1
  50. data/hobo_files/plugin/lib/hobo/model.rb +185 -66
  51. data/hobo_files/plugin/lib/hobo/model_controller.rb +56 -49
  52. data/hobo_files/plugin/lib/hobo/password_string.rb +2 -0
  53. data/hobo_files/plugin/lib/hobo/plugins.rb +75 -0
  54. data/hobo_files/plugin/lib/hobo/rapid_helper.rb +98 -0
  55. data/hobo_files/plugin/lib/hobo/static_tags +0 -3
  56. data/hobo_files/plugin/lib/hobo/textile_string.rb +11 -1
  57. data/hobo_files/plugin/lib/hobo/undefined.rb +1 -1
  58. data/hobo_files/plugin/lib/rexml.rb +166 -75
  59. data/hobo_files/plugin/spec/fixtures/users.yml +9 -0
  60. data/hobo_files/plugin/spec/spec.opts +6 -0
  61. data/hobo_files/plugin/spec/spec_helper.rb +28 -0
  62. data/hobo_files/plugin/spec/unit/hobo/dryml/template_spec.rb +650 -0
  63. data/hobo_files/plugin/tags/core.dryml +58 -4
  64. data/hobo_files/plugin/tags/rapid.dryml +289 -135
  65. data/hobo_files/plugin/tags/rapid_document_tags.dryml +49 -0
  66. data/hobo_files/plugin/tags/rapid_editing.dryml +92 -69
  67. data/hobo_files/plugin/tags/rapid_forms.dryml +242 -0
  68. data/hobo_files/plugin/tags/rapid_navigation.dryml +65 -65
  69. data/hobo_files/plugin/tags/rapid_pages.dryml +197 -124
  70. data/hobo_files/plugin/tags/rapid_support.dryml +23 -0
  71. metadata +29 -22
  72. data/hobo_files/plugin/generators/hobo_model/templates/migration.rb +0 -13
  73. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/default_mapping.rb +0 -11
  74. data/hobo_files/plugin/generators/hobo_user_model/templates/migration.rb +0 -15
  75. data/hobo_files/plugin/lib/hobo/HtmlString +0 -3
  76. data/hobo_files/plugin/lib/hobo/controller_helpers.rb +0 -135
  77. data/hobo_files/plugin/lib/hobo/core.rb +0 -475
  78. data/hobo_files/plugin/lib/hobo/rapid.rb +0 -447
  79. data/hobo_files/plugin/test/hobo_dryml_template_test.rb +0 -7
  80. data/hobo_files/plugin/test/hobo_test.rb +0 -7
@@ -4,23 +4,13 @@ Description:
4
4
  The generator takes a model name as its argument. The model name may be given in CamelCase or under_score and
5
5
  should not be suffixed with 'Model'.
6
6
 
7
- As additional parameters, the generator will take attribute pairs described by name and type. These attributes will
8
- be used to prepopulate the migration to create the table for the model and give you a set of predefined fixture.
9
- You don't have to think up all attributes up front, but it's a good idea of adding just the baseline of what's
10
- needed to start really working with the resource.
11
-
12
7
  The generator creates a model class in app/models, a test suite in test/unit, test fixtures in
13
- test/fixtures/singular_name.yml, and a migration in db/migrate.
8
+ test/fixtures/singular_name.yml.
14
9
 
15
10
  Examples:
16
- ./script/generate model account
11
+ ./script/generate hobo_model account
17
12
 
18
13
  This will create an Account model:
19
14
  Model: app/models/account.rb
20
15
  Test: test/unit/account_test.rb
21
16
  Fixtures: test/fixtures/accounts.yml
22
- Migration: db/migrate/XXX_add_accounts.rb
23
-
24
- ./script/generate model post title:string created_on:date body:text published:boolean
25
-
26
- Creates post model with predefined attributes.
@@ -1,5 +1,4 @@
1
1
  class HoboUserModelGenerator < Rails::Generator::NamedBase
2
- default_options :skip_migration => false
3
2
 
4
3
  def manifest
5
4
  record do |m|
@@ -15,24 +14,12 @@ class HoboUserModelGenerator < Rails::Generator::NamedBase
15
14
  m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
16
15
  m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
17
16
  m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml")
18
-
19
- unless options[:skip_migration]
20
- m.migration_template 'migration.rb', 'db/migrate', :assigns => {
21
- :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
22
- }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
23
- end
24
17
  end
25
18
  end
26
19
 
27
20
  protected
28
21
  def banner
29
- "Usage: #{$0} generate ModelName [field:type, field:type]"
22
+ "Usage: #{$0} #{spec.name} ModelName"
30
23
  end
31
24
 
32
- def add_options!(opt)
33
- opt.separator ''
34
- opt.separator 'Options:'
35
- opt.on("--skip-migration",
36
- "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
37
- end
38
25
  end
@@ -1,11 +1,5 @@
1
1
  # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2
2
  one:
3
3
  id: 1
4
- <% for attribute in attributes -%>
5
- <%= attribute.name %>: <%= attribute.default %>
6
- <% end -%>
7
4
  two:
8
5
  id: 2
9
- <% for attribute in attributes -%>
10
- <%= attribute.name %>: <%= attribute.default %>
11
- <% end -%>
@@ -3,14 +3,21 @@ class <%= class_name %> < ActiveRecord::Base
3
3
  hobo_model
4
4
 
5
5
  include Hobo::AuthenticatedUser
6
+
7
+ fields do
8
+ username :string
9
+ timestamps
10
+ end
6
11
 
7
12
  set_login_attr :username
8
13
 
9
- alias_attribute :display_name, :username
14
+ alias_attribute :to_s, :username
10
15
 
11
16
  # --- Hobo Permissions --- #
12
17
 
13
18
  def super_user?
19
+ # Return true to make this user exempt from permission restrictions
20
+ # e.g.
14
21
  # login == 'admin'
15
22
  end
16
23
 
@@ -15,6 +15,8 @@ require 'hobo/dryml/taglib'
15
15
  require 'hobo/dryml/template_environment'
16
16
  require 'hobo/dryml/template_handler'
17
17
 
18
+ require 'hobo/plugins'
19
+
18
20
  require 'extensions/test_case' if RAILS_ENV == "test"
19
21
 
20
22
 
@@ -33,8 +35,10 @@ class ActionController::Base
33
35
 
34
36
  end
35
37
 
36
- def (ActiveRecord::Base).hobo_model
37
- include Hobo::Model
38
+ class ActiveRecord::Base
39
+ def self.hobo_model
40
+ include Hobo::Model
41
+ end
38
42
  end
39
43
 
40
44
  # Default settings
@@ -1,24 +1,25 @@
1
1
  module ActiveRecord::Associations
2
2
 
3
3
  class HasManyAssociation
4
+
5
+ def hobo_has_many?
6
+ Hobo::Model.in?(@owner.class.included_modules)
7
+ end
4
8
 
5
- def new(*args)
6
- res = build(*args)
7
- if @owner.new_record?
8
- refl = @owner.class.reverse_reflection(@reflection.name)
9
- if refl
10
- bta = ActiveRecord::Associations::BelongsToAssociation.new(res, refl)
11
- bta.replace(@owner)
12
- res.instance_variable_set("@#{refl.name}", bta)
13
- end
14
- end
9
+ def build_with_reverse_reflection(*args)
10
+ res = build_without_reverse_reflection(*args)
11
+ set_reverse_association(res) if hobo_has_many?
15
12
  res
16
13
  end
14
+ alias_method_chain :build, :reverse_reflection
17
15
 
18
16
 
19
- def new_without_appending(attributes = {})
17
+ def new(attributes = {})
20
18
  record = @reflection.klass.new(attributes)
21
- set_belongs_to_association_for(record)
19
+ if hobo_has_many?
20
+ set_belongs_to_association_for(record)
21
+ set_reverse_association(record)
22
+ end
22
23
  record
23
24
  end
24
25
 
@@ -48,6 +49,16 @@ module ActiveRecord::Associations
48
49
  end
49
50
  alias_method_chain :find, :block
50
51
 
52
+ private
53
+
54
+ def set_reverse_association(object)
55
+ if @owner.new_record? && (refl = @owner.class.reverse_reflection(@reflection.name))
56
+ bta = ActiveRecord::Associations::BelongsToAssociation.new(object, refl)
57
+ bta.replace(@owner)
58
+ object.instance_variable_set("@#{refl.name}", bta)
59
+ end
60
+ end
61
+
51
62
  end
52
63
 
53
64
  end
@@ -1,43 +1,3 @@
1
- module Kernel
2
-
3
- def extract_options_from_args!(args) #:nodoc:
4
- args.last.is_a?(Hash) ? args.pop : {}
5
- end
6
-
7
- end
8
-
9
- class Object
10
-
11
- def in?(array)
12
- array.include?(self)
13
- end
14
-
15
- def not_in?(array)
16
- not array.include?(self)
17
- end
18
-
19
- alias_method :is_a_without_multiple_args?, :is_a?
20
- def is_a?(*args)
21
- args.any? {|a| is_a_without_multiple_args?(a) }
22
- end
23
-
24
- # metaid
25
- def metaclass; class << self; self; end; end
26
- def meta_eval &blk; metaclass.instance_eval &blk; end
27
-
28
- # Adds methods to a metaclass
29
- def meta_def name, &blk
30
- meta_eval { define_method name, &blk }
31
- end
32
-
33
- # Defines an instance method within a class
34
- def class_def name, &blk
35
- class_eval { define_method name, &blk }
36
- end
37
-
38
- end
39
-
40
-
41
1
  class Module
42
2
 
43
3
  def inheriting_attr_accessor(*names)
@@ -86,10 +46,70 @@ class Module
86
46
  EOS
87
47
  end
88
48
  end
49
+
50
+ private
51
+
52
+ def bool_attr_accessor(*args)
53
+ options = extract_options_from_args!(args)
54
+ (args + options.keys).each {|n| class_eval "def #{n}=(x); @#{n} = x; end" }
55
+
56
+ args.each {|n| class_eval "def #{n}?; !!@#{n}; end" }
57
+
58
+ options.keys.each do |n|
59
+ class_eval %(def #{n}?
60
+ if @#{n}.nil? && !instance_variables.include?("@\#{@#{n}}")
61
+ @#{n} = #{options[n].inspect}
62
+ else
63
+ @#{n}
64
+ end
65
+ end)
66
+ set_field_type(n => TrueClass) if respond_to?(:set_field_type)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ module Kernel
73
+
74
+ def extract_options_from_args!(args) #:nodoc:
75
+ args.last.is_a?(Hash) ? args.pop : {}
76
+ end
77
+
78
+ end
79
+
80
+ class Object
81
+
82
+ def in?(array)
83
+ array.include?(self)
84
+ end
85
+
86
+ def not_in?(array)
87
+ not array.include?(self)
88
+ end
89
+
90
+ alias_method :is_a_without_multiple_args?, :is_a?
91
+ def is_a?(*args)
92
+ args.any? {|a| is_a_without_multiple_args?(a) }
93
+ end
94
+
95
+ # metaid
96
+ def metaclass; class << self; self; end; end
97
+ def meta_eval &blk; metaclass.instance_eval &blk; end
98
+
99
+ # Adds methods to a metaclass
100
+ def meta_def name, &blk
101
+ meta_eval { define_method name, &blk }
102
+ end
89
103
 
104
+ # Defines an instance method within a class
105
+ def class_def name, &blk
106
+ class_eval { define_method name, &blk }
107
+ end
90
108
 
91
109
  end
92
110
 
111
+
112
+
93
113
  module Enumerable
94
114
 
95
115
  def omap(method = nil, &b)
@@ -149,6 +169,24 @@ module Enumerable
149
169
  each_with_index {|x, i| res << yield(x, i)}
150
170
  res
151
171
  end
172
+
173
+ def build_hash
174
+ res = {}
175
+ each do |x|
176
+ k, v = yield x
177
+ res[k] = v
178
+ end
179
+ res
180
+ end
181
+
182
+ def map_hash
183
+ res = {}
184
+ each do |x|
185
+ v = yield x
186
+ res[x] = v
187
+ end
188
+ res
189
+ end
152
190
 
153
191
  end
154
192
 
@@ -202,8 +240,57 @@ class Hash
202
240
  [yes, no]
203
241
  end
204
242
 
243
+ def -(keys)
244
+ res = {}
245
+ each_pair {|k, v| res[k] = v unless k.in?(keys)}
246
+ res
247
+ end
248
+
249
+ def &(keys)
250
+ res = {}
251
+ keys.each {|k| res[k] = self[k] if has_key?(k)}
252
+ res
253
+ end
254
+
255
+ end
256
+
257
+
258
+ class HashWithIndifferentAccess
259
+
260
+ def -(keys)
261
+ res = {}
262
+ keys = keys.map {|k| k.is_a?(Symbol) ? k.to_s : k }
263
+ each_pair { |k, v| res[k] = v unless k.in?(keys) }
264
+ res
265
+ end
266
+
267
+ def &(keys)
268
+ res = {}
269
+ keys.each do |k|
270
+ k = k.to_s if k.is_a?(Symbol)
271
+ res[k] = self[k] if has_key?(k)
272
+ end
273
+ res
274
+ end
275
+
276
+ def partition_hash(keys=nil)
277
+ keys = keys.map {|k| k.is_a?(Symbol) ? k.to_s : k }
278
+ yes = {}
279
+ no = {}
280
+ each do |k,v|
281
+ if block_given? ? yield(k,v) : keys.include?(k)
282
+ yes[k] = v
283
+ else
284
+ no[k] = v
285
+ end
286
+ end
287
+ [yes, no]
288
+ end
289
+
290
+
205
291
  end
206
292
 
293
+
207
294
  class <<ActiveRecord::Base
208
295
  alias_method :[], :find
209
296
  end
@@ -243,3 +330,10 @@ module PP::ObjectMixin
243
330
 
244
331
  end
245
332
 
333
+ class Proc
334
+
335
+ def call_with_block(*args, &b)
336
+ call(*args + [b])
337
+ end
338
+
339
+ end
@@ -13,7 +13,6 @@ class Test::Unit::TestCase
13
13
  module HoboTesting
14
14
 
15
15
  class HoboHelpers
16
- include Hobo::ControllerHelpers
17
16
 
18
17
  def urlb
19
18
  "http://example.com"
@@ -5,11 +5,20 @@ module Hobo
5
5
  class RawJs < String; end
6
6
 
7
7
  @models = []
8
-
8
+ @field_types = HashWithIndifferentAccess.new
9
+
9
10
  class << self
10
11
 
11
- attr_accessor :current_theme
12
+ attr_accessor :current_theme, :field_types
12
13
  attr_writer :developer_features
14
+
15
+ def symbolic_type_name(type)
16
+ field_types.index(type)
17
+ end
18
+
19
+ def type_name(type)
20
+ symbolic_type_name(type) || type.name.underscore.gsub("/", "__")
21
+ end
13
22
 
14
23
  def developer_features?
15
24
  @developer_features
@@ -19,8 +28,8 @@ module Hobo
19
28
  def raw_js(s)
20
29
  RawJs.new(s)
21
30
  end
22
-
23
-
31
+
32
+
24
33
  def user_model=(model)
25
34
  @user_model = model && model.name
26
35
  end
@@ -39,7 +48,7 @@ module Hobo
39
48
  def models
40
49
  unless @models_loaded
41
50
  Dir.entries("#{RAILS_ROOT}/app/models/").map do |f|
42
- f =~ /.rb$/ and f.sub(/.rb$/, '').camelize.constantize
51
+ f =~ /^[a-zA-Z_][a-zA-Z0-9_]*\.rb$/ and f.sub(/.rb$/, '').camelize.constantize
43
52
  end
44
53
  @models_loaded = true
45
54
  end
@@ -124,12 +133,15 @@ module Hobo
124
133
  end
125
134
 
126
135
  def add_routes(map)
136
+ ActiveRecord::Base.connection.reconnect! unless ActiveRecord::Base.connection.active?
127
137
  require "#{RAILS_ROOT}/app/controllers/application" unless Object.const_defined? :ApplicationController
128
-
138
+ require "#{RAILS_ROOT}/app/assemble.rb" if File.exists? "#{RAILS_ROOT}/app/assemble.rb"
139
+
129
140
  for model in Hobo.models
130
141
  controller_name = "#{model.name.pluralize}Controller"
131
- controller = controller_name.constantize if
142
+ controller = controller_name.constantize if (Object.const_defined? controller_name) ||
132
143
  File.exists?("#{RAILS_ROOT}/app/controllers/#{controller_name.underscore}.rb")
144
+
133
145
  if controller
134
146
  web_name = model.name.underscore.pluralize.downcase
135
147
 
@@ -156,7 +168,7 @@ module Hobo
156
168
 
157
169
  for view in controller.show_actions
158
170
  map.named_route("#{web_name.singularize}_#{view}",
159
- "#{web_name}/:id;#{view}",
171
+ "#{web_name}/:id/#{view}",
160
172
  :controller => web_name,
161
173
  :action => view.to_s,
162
174
  :conditions => { :method => :get })
@@ -210,10 +222,10 @@ module Hobo
210
222
  def can_create?(person, object)
211
223
  if object.is_a?(Class) and object < ActiveRecord::Base
212
224
  object = object.new
213
- object.created_by(person)
225
+ object.set_creator(person)
214
226
  elsif Hobo.simple_has_many_association?(object)
215
- object = object.new_without_appending
216
- object.created_by(person)
227
+ object = object.new
228
+ object.set_creator(person)
217
229
  end
218
230
  check_permission(:create, person, object)
219
231
  end
@@ -225,34 +237,49 @@ module Hobo
225
237
 
226
238
 
227
239
  def can_edit?(person, object, field)
228
- setter = "#{field}="
240
+ setter = "#{field.to_s.sub /\?$/, ''}="
229
241
  return false unless can_view?(person, object, field) and object.respond_to?(setter)
230
242
 
231
243
  refl = object.class.reflections[field.to_sym] if object.is_a?(ActiveRecord::Base)
232
244
 
233
245
  # has_many and polymorphic associations are not editable (for now)
234
- return false if refl and (refl.macro == :has_many or refl.options[:polymorphic])
235
-
236
- current = object.send(field)
237
- new = object.duplicate
238
- new.send(setter, if current == true
239
- false
240
- elsif current == false
241
- true
242
- elsif refl and refl.macro == :belongs_to
243
- Hobo::Undefined.new(refl.klass)
244
- else
245
- Hobo::Undefined.new
246
- end)
247
-
248
- begin
249
- if object.new_record?
250
- check_permission(:create, person, new)
251
- else
252
- check_permission(:update, person, object, new)
246
+ return false if refl and (refl.macro == :has_many or refl.options[:polymorphic] or refl.macro == :has_one)
247
+
248
+ if object.respond_to?(:editable_by?)
249
+ check_permission(:edit, person, object, field.to_sym)
250
+ else
251
+ # Fake an edit test by setting the field in question to
252
+ # Hobo::Undefined and then testing for update permission
253
+
254
+ current = object.send(field)
255
+ new = object.duplicate
256
+
257
+ begin
258
+ # Setting the undefined value can sometimes result in an
259
+ # UndefinedAccessError. In that case we have no choice but
260
+ # return false.
261
+ new.send(setter, if current == true
262
+ false
263
+ elsif current == false
264
+ true
265
+ elsif refl and refl.macro == :belongs_to
266
+ Hobo::Undefined.new(refl.klass)
267
+ else
268
+ Hobo::Undefined.new
269
+ end)
270
+ rescue Hobo::UndefinedAccessError
271
+ raise HoboError, "#{object.class.name} does not support undefined assignements, define editable_by(user, field)"
272
+ end
273
+
274
+ begin
275
+ if object.new_record?
276
+ check_permission(:create, person, new)
277
+ else
278
+ check_permission(:update, person, object, new)
279
+ end
280
+ rescue Hobo::UndefinedAccessError
281
+ false
253
282
  end
254
- rescue Hobo::UndefinedAccessError
255
- false
256
283
  end
257
284
  end
258
285
 
@@ -264,12 +291,12 @@ module Hobo
264
291
 
265
292
  # can_view? has special behaviour if it's passed a class or an
266
293
  # association-proxy -- it instantiates the class, or creates a new
267
- # instance "in" the association (new_without_appending), and tests
268
- # the permission of this object. This means the permission methods
269
- # in models can't rely on the instance being properly initialised.
270
- # But it's important that it works like this because, in the case
271
- # of an association proxy, we don't want to loose the information
272
- # that the object belongs_to the proxy owner.
294
+ # instance "in" the association, and tests the permission of this
295
+ # object. This means the permission methods in models can't rely
296
+ # on the instance being properly initialised. But it's important
297
+ # that it works like this because, in the case of an association
298
+ # proxy, we don't want to loose the information that the object
299
+ # belongs_to the proxy owner.
273
300
  def can_view?(person, object, field=nil)
274
301
  if field
275
302
  field = field.to_sym if field.is_a? String
@@ -278,12 +305,8 @@ module Hobo
278
305
  # Special support for classes (can view instances?)
279
306
  if object.is_a?(Class) and object < ActiveRecord::Base
280
307
  object = object.new
281
- elsif object.is_a?(Array)
282
- if object.respond_to?(:new_without_appending)
283
- object = object.new_without_appending
284
- elsif object.respond_to?(:member_class)
285
- object = object.member_class.new
286
- end
308
+ elsif Hobo.simple_has_many_association?(object)
309
+ object = object.new
287
310
  end
288
311
  end
289
312
  viewable = check_permission(:view, person, object, field)
@@ -309,10 +332,16 @@ module Hobo
309
332
 
310
333
  def static_tags
311
334
  @static_tags ||= begin
312
- path = File.join(File.dirname(__FILE__), "hobo/static_tags")
335
+ path = if FileTest.exists?("#{RAILS_ROOT}/config/dryml_static_tags.txt")
336
+ "#{RAILS_ROOT}/config/dryml_static_tags.txt"
337
+ else
338
+ File.join(File.dirname(__FILE__), "hobo/static_tags")
339
+ end
313
340
  File.readlines(path).omap{chop}
314
341
  end
315
342
  end
343
+
344
+ attr_writer :static_tags
316
345
 
317
346
 
318
347
  private
@@ -327,6 +356,7 @@ module Hobo
327
356
  when :create; :creatable_by?
328
357
  when :update; :updatable_by?
329
358
  when :delete; :deletable_by?
359
+ when :edit; :editable_by?
330
360
  when :view; :viewable_by?
331
361
  end
332
362
  p = if object.respond_to?(obj_method)
@@ -349,5 +379,6 @@ module Hobo
349
379
  end
350
380
 
351
381
  end
382
+
352
383
 
353
384
  end