hobo 0.9.0 → 0.9.100
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.
- data/CHANGES.txt +132 -0
- data/Rakefile +18 -22
- data/bin/hobo +14 -13
- data/doctest/scopes.rdoctest +1 -0
- data/dryml_generators/rapid/forms.dryml.erb +1 -1
- data/dryml_generators/rapid/pages.dryml.erb +24 -24
- data/lib/hobo.rb +3 -3
- data/lib/hobo/accessible_associations.rb +10 -3
- data/lib/hobo/controller.rb +2 -1
- data/lib/hobo/dryml.rb +7 -2
- data/lib/hobo/dryml/dryml_builder.rb +1 -4
- data/lib/hobo/dryml/dryml_generator.rb +5 -3
- data/lib/hobo/dryml/taglib.rb +3 -8
- data/lib/hobo/dryml/template.rb +3 -10
- data/lib/hobo/dryml/template_handler.rb +3 -2
- data/lib/hobo/hobo_helper.rb +5 -83
- data/lib/hobo/lifecycles.rb +9 -5
- data/lib/hobo/lifecycles/actions.rb +5 -5
- data/lib/hobo/lifecycles/lifecycle.rb +6 -2
- data/lib/hobo/model.rb +14 -36
- data/lib/hobo/model_controller.rb +28 -15
- data/lib/hobo/model_router.rb +1 -1
- data/lib/hobo/permissions.rb +55 -5
- data/lib/hobo/permissions/associations.rb +13 -5
- data/lib/hobo/rapid_helper.rb +4 -10
- data/lib/hobo/scopes/automatic_scopes.rb +9 -1
- data/lib/hobo/translations.rb +88 -0
- data/lib/hobo/user.rb +1 -2
- data/lib/hobo/user_controller.rb +31 -9
- data/lib/hobo/view_hints.rb +38 -6
- data/rails_generators/hobo_model/templates/hints.rb +4 -1
- data/rails_generators/hobo_model_controller/hobo_model_controller_generator.rb +1 -1
- data/rails_generators/hobo_rapid/hobo_rapid_generator.rb +2 -1
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +9 -0
- data/rails_generators/hobo_rapid/templates/ie7-recalc.js +166 -2
- data/rails_generators/hobo_user_model/templates/model.rb +1 -3
- data/taglibs/rapid.dryml +2 -1
- data/taglibs/rapid_core.dryml +7 -5
- data/taglibs/rapid_editing.dryml +14 -10
- data/taglibs/rapid_forms.dryml +7 -5
- data/taglibs/rapid_generics.dryml +1 -1
- data/taglibs/rapid_lifecycles.dryml +3 -2
- data/taglibs/rapid_pages.dryml +1 -1
- data/taglibs/rapid_support.dryml +1 -1
- data/tasks/hobo_tasks.rake +10 -0
- metadata +7 -7
- data/lib/hobo/bundle.rb +0 -330
data/lib/hobo.rb
CHANGED
@@ -16,7 +16,7 @@ class HoboError < RuntimeError; end
|
|
16
16
|
|
17
17
|
module Hobo
|
18
18
|
|
19
|
-
VERSION = "0.9.
|
19
|
+
VERSION = "0.9.100"
|
20
20
|
|
21
21
|
class PermissionDeniedError < RuntimeError; end
|
22
22
|
|
@@ -105,13 +105,13 @@ module Hobo
|
|
105
105
|
Array(path)
|
106
106
|
end
|
107
107
|
|
108
|
-
|
108
|
+
parent = nil
|
109
109
|
path.each do |field|
|
110
110
|
return nil if object.nil?
|
111
111
|
parent = object
|
112
112
|
object = get_field(parent, field)
|
113
113
|
end
|
114
|
-
[parent,
|
114
|
+
[parent, path.last, object]
|
115
115
|
end
|
116
116
|
|
117
117
|
|
@@ -42,8 +42,15 @@ module Hobo
|
|
42
42
|
|
43
43
|
record = yield id
|
44
44
|
record.attributes = hash
|
45
|
-
|
46
|
-
|
45
|
+
if owner.new_record? && record.new_record?
|
46
|
+
# work around
|
47
|
+
# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3510-has_many-build-does-not-set-reverse-reflection
|
48
|
+
# https://hobo.lighthouseapp.com/projects/8324/tickets/447-validation-problems-with-has_many-accessible-true
|
49
|
+
method = "#{owner.class.reverse_reflection(association_name).name}=".to_sym
|
50
|
+
record.send(method, owner) if record.respond_to? method
|
51
|
+
else
|
52
|
+
owner.include_in_save(association_name, record)
|
53
|
+
end
|
47
54
|
else
|
48
55
|
# It's already a record
|
49
56
|
record = record_hash_or_string
|
@@ -87,7 +94,7 @@ module Hobo
|
|
87
94
|
|
88
95
|
classy_module(AccessibleAssociations) do
|
89
96
|
|
90
|
-
include IncludeInSave
|
97
|
+
include Hobo::IncludeInSave
|
91
98
|
|
92
99
|
# --- has_many mass assignment support --- #
|
93
100
|
|
data/lib/hobo/controller.rb
CHANGED
@@ -14,6 +14,7 @@ module Hobo
|
|
14
14
|
|
15
15
|
def included_in_class(klass)
|
16
16
|
klass.extend(ClassMethods)
|
17
|
+
klass.send(:include, Hobo::Translations)
|
17
18
|
klass.class_eval do
|
18
19
|
before_filter :login_from_cookie
|
19
20
|
alias_method_chain :redirect_to, :object_url
|
@@ -157,7 +158,7 @@ module Hobo
|
|
157
158
|
end
|
158
159
|
|
159
160
|
def not_found(error)
|
160
|
-
if
|
161
|
+
if self.class.superclass.method_defined?("not_found_response")
|
161
162
|
super
|
162
163
|
elsif render_tag("not-found-page", {}, :status => 404)
|
163
164
|
# cool
|
data/lib/hobo/dryml.rb
CHANGED
@@ -24,9 +24,9 @@ module Hobo
|
|
24
24
|
CORE_TAGLIB = { :src => "core", :plugin => "hobo" }
|
25
25
|
|
26
26
|
DEFAULT_IMPORTS = (if defined?(ApplicationHelper)
|
27
|
-
[Hobo::HoboHelper, ApplicationHelper]
|
27
|
+
[Hobo::HoboHelper, Hobo::Translations, ApplicationHelper]
|
28
28
|
else
|
29
|
-
[Hobo::HoboHelper]
|
29
|
+
[Hobo::HoboHelper, Hobo::Translations]
|
30
30
|
end)
|
31
31
|
|
32
32
|
@renderer_classes = {}
|
@@ -38,6 +38,11 @@ module Hobo
|
|
38
38
|
|
39
39
|
def enable
|
40
40
|
ActionView::Template.register_template_handler("dryml", Hobo::Dryml::TemplateHandler)
|
41
|
+
if ActionView::Template.respond_to? :exempt_from_layout
|
42
|
+
ActionView::Template.exempt_from_layout('dryml')
|
43
|
+
elsif
|
44
|
+
ActionView::Base.exempt_from_layout('dryml')
|
45
|
+
end
|
41
46
|
DrymlGenerator.enable
|
42
47
|
end
|
43
48
|
|
@@ -61,7 +61,7 @@ module Hobo::Dryml
|
|
61
61
|
def erb_process(erb_src, method_def=false)
|
62
62
|
trim_mode = ActionView::TemplateHandlers::ERB.erb_trim_mode
|
63
63
|
erb = ERB.new(erb_src, nil, trim_mode, "output_buffer")
|
64
|
-
src = erb.src
|
64
|
+
src = erb.src.split(';')[1..-2].join(';')
|
65
65
|
|
66
66
|
if method_def
|
67
67
|
src.sub /^\s*def.*?\(.*?\)/, '\0 __in_erb_template=true; '
|
@@ -118,9 +118,6 @@ module Hobo::Dryml
|
|
118
118
|
template_dir = File.dirname(template_path)
|
119
119
|
options = options.merge(:template_dir => template_dir)
|
120
120
|
|
121
|
-
# Pass on the current bundle, if there is one, to the sub-taglib
|
122
|
-
options[:bundle] = template.bundle.name unless template.bundle.nil? || options[:bundle] || options[:plugin]
|
123
|
-
|
124
121
|
taglib = Taglib.get(options)
|
125
122
|
taglib.import_into(@environment, options[:as])
|
126
123
|
end
|
@@ -75,6 +75,9 @@ module Hobo
|
|
75
75
|
|
76
76
|
|
77
77
|
def run
|
78
|
+
# Ensure all view hints loaded before running
|
79
|
+
Hobo::Model.all_models.*.view_hints
|
80
|
+
|
78
81
|
[nil, *Hobo.subsites].each { |s| run_for_subsite(s) }
|
79
82
|
end
|
80
83
|
|
@@ -156,11 +159,10 @@ module Hobo
|
|
156
159
|
|
157
160
|
|
158
161
|
def model_name(*options)
|
159
|
-
name = model.view_hints.model_name
|
160
|
-
name = name.pluralize if :plural.in?(options)
|
161
|
-
name = name.titleize if :title.in?(options)
|
162
|
+
name = :plural.in?(options) ? model.view_hints.model_name_plural : model.view_hints.model_name
|
162
163
|
name = name.titleize.downcase if :lowercase.in?(options)
|
163
164
|
name = name.underscore.gsub('_', '-').gsub('/', '--') if :dashed.in?(options)
|
165
|
+
name = name.camelize if :camel.in?(options)
|
164
166
|
name
|
165
167
|
end
|
166
168
|
|
data/lib/hobo/dryml/taglib.rb
CHANGED
@@ -14,8 +14,7 @@ module Hobo
|
|
14
14
|
if taglib
|
15
15
|
taglib.reload
|
16
16
|
else
|
17
|
-
|
18
|
-
taglib = Taglib.new(src_file, bundle)
|
17
|
+
taglib = Taglib.new(src_file)
|
19
18
|
@cache[src_file] = taglib
|
20
19
|
end
|
21
20
|
taglib
|
@@ -33,9 +32,6 @@ module Hobo
|
|
33
32
|
"#{HOBO_ROOT}/taglibs"
|
34
33
|
elsif plugin
|
35
34
|
"#{RAILS_ROOT}/vendor/plugins/#{plugin}/taglibs"
|
36
|
-
elsif (bundle_name = options[:bundle])
|
37
|
-
bundle = Bundle.bundles[bundle_name] or raise ArgumentError, "No such bundle: #{options[:bundle]}"
|
38
|
-
"#{RAILS_ROOT}/vendor/plugins/#{bundle.plugin}/taglibs"
|
39
35
|
elsif options[:src] =~ /\//
|
40
36
|
"#{RAILS_ROOT}/app/views"
|
41
37
|
elsif options[:template_dir] =~ /^#{HOBO_ROOT}/
|
@@ -52,9 +48,8 @@ module Hobo
|
|
52
48
|
|
53
49
|
end
|
54
50
|
|
55
|
-
def initialize(src_file
|
51
|
+
def initialize(src_file)
|
56
52
|
@src_file = src_file
|
57
|
-
@bundle = bundle
|
58
53
|
load
|
59
54
|
end
|
60
55
|
|
@@ -92,7 +87,7 @@ module Hobo
|
|
92
87
|
end
|
93
88
|
|
94
89
|
end
|
95
|
-
template = Template.new(File.read(@src_file), @module, @src_file
|
90
|
+
template = Template.new(File.read(@src_file), @module, @src_file)
|
96
91
|
template.compile([], [])
|
97
92
|
@last_load_time = File.mtime(@src_file)
|
98
93
|
end
|
data/lib/hobo/dryml/template.rb
CHANGED
@@ -33,11 +33,10 @@ module Hobo::Dryml
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def initialize(src, environment, template_path
|
36
|
+
def initialize(src, environment, template_path)
|
37
37
|
@src = src
|
38
38
|
@environment = environment # a class or a module
|
39
39
|
@template_path = template_path.sub(%r(^#{Regexp.escape(RAILS_ROOT)}/), "")
|
40
|
-
@bundle = bundle
|
41
40
|
|
42
41
|
@builder = Template.build_cache[@template_path] || DRYMLBuilder.new(self)
|
43
42
|
@builder.set_environment(environment)
|
@@ -45,7 +44,7 @@ module Hobo::Dryml
|
|
45
44
|
@last_element = nil
|
46
45
|
end
|
47
46
|
|
48
|
-
attr_reader :tags, :template_path
|
47
|
+
attr_reader :tags, :template_path
|
49
48
|
|
50
49
|
def compile(local_names=[], auto_taglibs=[])
|
51
50
|
now = Time.now
|
@@ -178,7 +177,7 @@ module Hobo::Dryml
|
|
178
177
|
require_toplevel(el)
|
179
178
|
require_attribute(el, "as", /^#{DRYML_NAME}$/, true)
|
180
179
|
options = {}
|
181
|
-
%w(src module plugin
|
180
|
+
%w(src module plugin as).each do |attr|
|
182
181
|
options[attr.to_sym] = el.attributes[attr] if el.attributes[attr]
|
183
182
|
end
|
184
183
|
@builder.add_build_instruction(:include, options)
|
@@ -261,8 +260,6 @@ module Hobo::Dryml
|
|
261
260
|
klass = HoboFields.to_class(for_type) or
|
262
261
|
dryml_exception("No such type in polymorphic tag definition: '#{for_type}'", el)
|
263
262
|
klass.name
|
264
|
-
elsif for_type =~ /^_.*_$/
|
265
|
-
rename_class(for_type)
|
266
263
|
else
|
267
264
|
for_type
|
268
265
|
end.underscore.gsub('/', '__')
|
@@ -994,10 +991,6 @@ module Hobo::Dryml
|
|
994
991
|
"#{name}_#{@gensym_counter}"
|
995
992
|
end
|
996
993
|
|
997
|
-
def rename_class(name)
|
998
|
-
@bundle && name.starts_with?("_") ? @bundle.send(name) : name
|
999
|
-
end
|
1000
|
-
|
1001
994
|
def include_source_metadata
|
1002
995
|
# disabled for now -- we're still getting broken rendering with this feature on
|
1003
996
|
return false
|
@@ -17,7 +17,8 @@ module Hobo::Dryml
|
|
17
17
|
|
18
18
|
def render_for_rails22(template, view, local_assigns)
|
19
19
|
renderer = Hobo::Dryml.page_renderer_for_template(view, local_assigns.keys, template)
|
20
|
-
this =
|
20
|
+
this = view.controller.send(:dryml_context) || local_assigns[:this]
|
21
|
+
@view._?.instance_variable_set("@this", this)
|
21
22
|
s = renderer.render_page(this, local_assigns)
|
22
23
|
|
23
24
|
# Important to strip whitespace, or the browser hangs around for ages (FF2)
|
@@ -177,7 +178,7 @@ module ActionView
|
|
177
178
|
end
|
178
179
|
end
|
179
180
|
|
180
|
-
if
|
181
|
+
if method_defined? "find_template"
|
181
182
|
# only rails 2.3 has this function
|
182
183
|
alias_method_chain :find_template, :dryml
|
183
184
|
end
|
data/lib/hobo/hobo_helper.rb
CHANGED
@@ -143,7 +143,7 @@ module Hobo
|
|
143
143
|
|
144
144
|
def type_id(type=nil)
|
145
145
|
type ||= (this.is_a?(Class) && this) || this_type || this.class
|
146
|
-
HoboFields.to_name(type) || type.name.underscore.gsub("/", "__")
|
146
|
+
HoboFields.to_name(type) || type.name.to_s.underscore.gsub("/", "__")
|
147
147
|
end
|
148
148
|
|
149
149
|
|
@@ -485,15 +485,13 @@ module Hobo
|
|
485
485
|
# --- ViewHint Helpers --- #
|
486
486
|
|
487
487
|
def this_field_name
|
488
|
-
|
489
|
-
default = this_parent.class.try.view_hints.try.field_name(this_field) || this_field
|
490
|
-
I18n.t(key, :default => default, :scope => [:activerecord, :attributes], :count => 1)
|
488
|
+
this_parent.class.try.view_hints.try.field_name(this_field) || this_field
|
491
489
|
end
|
492
490
|
|
493
491
|
def this_field_help
|
494
|
-
key = "#{this_parent.class.try.name.
|
492
|
+
key = "#{this_parent.class.try.name.tableize}.hints.#{this_field.to_s}"
|
495
493
|
default = this_parent.class.try.view_hints.try.field_help[this_field.to_sym] || ""
|
496
|
-
|
494
|
+
Hobo::Translations.ht(key, :default=>default)
|
497
495
|
end
|
498
496
|
|
499
497
|
|
@@ -510,83 +508,7 @@ module Hobo
|
|
510
508
|
logger.debug("DRYML THIS = #{this.typed_id rescue this.inspect}")
|
511
509
|
logger.debug("###################\n")
|
512
510
|
args.first unless args.empty?
|
513
|
-
end
|
514
|
-
|
515
|
-
# --- Translation Helper --- #
|
516
|
-
#
|
517
|
-
# Uses RoR native I18n.translate.
|
518
|
-
#
|
519
|
-
# Adds some conventions for easier hobo translation.
|
520
|
-
# 1. Assumes the first part of the key to be a model name (e.g.: users.index.title -> user)
|
521
|
-
# 2. Tries to translate the model by lookup for: (e.g.: user-> activerecord.models.user)
|
522
|
-
# 3. Adds a default fallback to the beginning of the fallback chain
|
523
|
-
# by replacing the first part of the key with "hobo" and using the translated model name
|
524
|
-
# as additional attribute. This allows us to have default translations
|
525
|
-
# (e.g.: hobo.index.title: "{{model}} Index")
|
526
|
-
#
|
527
|
-
# Is also used as a tag in the dryml-view files. The syntax is:
|
528
|
-
# <ht key="my.app">My Application</ht>
|
529
|
-
# --> Will lookup the "my.app"-key for your locale and replaces the "My Application" content
|
530
|
-
# if found.
|
531
|
-
#
|
532
|
-
# <ht key="my" app="Program">My Application</ht>
|
533
|
-
# --> Will look up both the "my"- and "app"-key for your locale, and replaces the
|
534
|
-
# "My Application" with the "my"-key contents (interpolated using the "app"-key.
|
535
|
-
# sample.en.yml-file:
|
536
|
-
# "no":
|
537
|
-
# my: "Mitt {{app}}"
|
538
|
-
# The output should be: Mitt Program
|
539
|
-
#
|
540
|
-
# Otherwise with features as the ht method, step 1, 2 and 3 above.
|
541
|
-
def ht(key, options={})
|
542
|
-
|
543
|
-
# Check if called as a tag, i.e. like this <ht></ht>
|
544
|
-
if (key.class == Hash)
|
545
|
-
if key.has_key?(:default) && !key[:default].blank?
|
546
|
-
logger.warn "hobo-i18n: 'default' should not be used as an attribute on the ht-tag. If used, then you need to make sure that the tags inner-contents are not used. These are normally treated as defaults automatically, but if there is a default attribute then that inner-content will be hidden from this method - and will not be replaced with the translation found."
|
547
|
-
end
|
548
|
-
defaults = options[:default];
|
549
|
-
# Swap key and options, remove options[:key]
|
550
|
-
options = key
|
551
|
-
key = options.delete(:key) # returns value for options[:key] as well as deleting it
|
552
|
-
# Set options[:default] to complete the tag-argument-conversion process.
|
553
|
-
options[:default] = (defaults.class == Proc) ? [defaults.call(options)] : (options[:default].blank? ? [] : [options[:default]])
|
554
|
-
else
|
555
|
-
# Not called as a tag. Prepare options[:default].
|
556
|
-
if options[:default].blank?
|
557
|
-
options[:default]=[]
|
558
|
-
elsif options[:default].class != Array
|
559
|
-
options[:default] = [options[:default]]
|
560
|
-
end
|
561
|
-
end
|
562
|
-
|
563
|
-
# assume the first part of the key to be the model
|
564
|
-
keys = key.to_s.split(".")
|
565
|
-
if keys.length > 1
|
566
|
-
model = keys.shift()
|
567
|
-
subkey = keys.join(".")
|
568
|
-
else
|
569
|
-
subkey = key
|
570
|
-
end
|
571
|
-
|
572
|
-
# add :"hobo.#{key}" as the first fallback
|
573
|
-
options[:default].unshift("hobo.#{subkey}".to_sym)
|
574
|
-
|
575
|
-
# translate the model
|
576
|
-
unless model.blank?
|
577
|
-
translated_model = I18n.translate( "activerecord.models.#{model.singularize.underscore}", :default=>model).titleize
|
578
|
-
options[:model] = translated_model
|
579
|
-
end
|
580
|
-
|
581
|
-
begin
|
582
|
-
key_prefix = "<span class='translation-key'>#{key}</span>" if HOBO_SHOW_LOCALE_KEYS
|
583
|
-
rescue
|
584
|
-
puts "Set HOBO_SHOW_LOCALE_KEYS=true in your environment to get all locale keys displayed"
|
585
|
-
end
|
586
|
-
|
587
|
-
logger.info "..translate(#{key}, #{options.inspect}) to #{I18n.locale}"
|
588
|
-
I18n.translate(key.to_sym, options)+(key_prefix ? key_prefix:"")
|
589
|
-
end
|
511
|
+
end
|
590
512
|
|
591
513
|
end
|
592
514
|
|
data/lib/hobo/lifecycles.rb
CHANGED
@@ -30,13 +30,17 @@ module Hobo
|
|
30
30
|
module_eval "class ::#{name}::Lifecycle < Hobo::Lifecycles::Lifecycle; end"
|
31
31
|
lifecycle = self::Lifecycle
|
32
32
|
lifecycle.init(self, options)
|
33
|
+
|
34
|
+
module_eval "class ::#{name}::LifecycleStateField < HoboFields::LifecycleState; end"
|
35
|
+
state_field_class = self::LifecycleStateField
|
36
|
+
state_field_class.table_name = name.tableize
|
33
37
|
end
|
34
38
|
|
35
|
-
dsl = DeclarationDSL.new(lifecycle)
|
39
|
+
dsl = Hobo::Lifecycles::DeclarationDSL.new(lifecycle)
|
36
40
|
dsl.instance_eval(&block)
|
37
41
|
|
38
42
|
default = lifecycle.default_state ? { :default => lifecycle.default_state.name.to_s } : {}
|
39
|
-
declare_field(options[:state_field],
|
43
|
+
declare_field(options[:state_field], state_field_class, default)
|
40
44
|
unless options[:index] == false
|
41
45
|
index_options = { :name => options[:index] } unless options[:index] == true
|
42
46
|
index(options[:state_field], index_options || {})
|
@@ -82,15 +86,15 @@ module Hobo
|
|
82
86
|
|
83
87
|
|
84
88
|
def lifecycle
|
85
|
-
@lifecycle ||= if
|
89
|
+
@lifecycle ||= if self.class.const_defined?(:Lifecycle)
|
86
90
|
self.class::Lifecycle.new(self)
|
87
91
|
else
|
88
92
|
# search through superclasses
|
89
93
|
current = self.class.superclass
|
90
|
-
until (
|
94
|
+
until (current.const_defined?(:Lifecycle) || current.nil? || !current.respond_to?(:lifecycle)) do
|
91
95
|
current = current.superclass
|
92
96
|
end
|
93
|
-
current
|
97
|
+
current::Lifecycle.new(self) if current.const_defined?(:Lifecycle)
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
@@ -15,11 +15,8 @@ module Hobo
|
|
15
15
|
return true if available_to.nil? # available_to not specified (these steps are not published)
|
16
16
|
acting_user_is?(available_to, record)
|
17
17
|
end
|
18
|
-
|
19
|
-
|
20
|
-
def acting_user_is?(who, record)
|
21
|
-
user = record.acting_user
|
22
18
|
|
19
|
+
def publishable_by(user, who, record)
|
23
20
|
case who
|
24
21
|
when :all
|
25
22
|
true
|
@@ -32,7 +29,7 @@ module Hobo
|
|
32
29
|
|
33
30
|
when Array
|
34
31
|
# recursively apply the same test to every item in the array
|
35
|
-
who.detect { |w|
|
32
|
+
who.detect { |w| publishable_by(user, w, record) }
|
36
33
|
|
37
34
|
else
|
38
35
|
refl = record.class.reflections[who]
|
@@ -53,6 +50,9 @@ module Hobo
|
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
53
|
+
def acting_user_is?(who, record)
|
54
|
+
publishable_by(record.acting_user, who, record)
|
55
|
+
end
|
56
56
|
|
57
57
|
def run_hook(record, hook, *args)
|
58
58
|
case hook
|
@@ -159,7 +159,7 @@ module Hobo
|
|
159
159
|
state ? state.transitions_out : []
|
160
160
|
end
|
161
161
|
|
162
|
-
|
162
|
+
# see also publishable_transitions_for
|
163
163
|
def available_transitions_for(user, name=nil)
|
164
164
|
name = name.to_sym if name
|
165
165
|
matches = available_transitions
|
@@ -169,6 +169,10 @@ module Hobo
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
+
def publishable_transitions_for(user)
|
173
|
+
available_transitions_for(user).select {|t| t.publishable_by(user, t.available_to, record)}
|
174
|
+
end
|
175
|
+
|
172
176
|
|
173
177
|
def become(state_name, validate=true)
|
174
178
|
state_name = state_name.to_sym
|
@@ -180,7 +184,7 @@ module Hobo
|
|
180
184
|
else
|
181
185
|
s = self.class.states[state_name]
|
182
186
|
raise ArgumentError, "No such state '#{state_name}' for #{record.class.name}" unless s
|
183
|
-
|
187
|
+
|
184
188
|
if record.save(validate)
|
185
189
|
s.activate! record
|
186
190
|
self.active_step = nil # That's the end of this step
|