hobo 0.5.3 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
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