active_scaffold 3.1.4 → 3.1.5
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/lib/active_scaffold/actions/nested.rb +6 -2
- data/lib/active_scaffold/actions/nested.rb~ +7 -5
- data/lib/active_scaffold/actions/update.rb~ +2 -3
- data/lib/active_scaffold/bridges/shared/date_bridge.rb~ +209 -0
- data/lib/active_scaffold/config/nested.rb +1 -0
- data/lib/active_scaffold/config/nested.rb~ +41 -0
- data/lib/active_scaffold/constraints.rb~ +186 -0
- data/lib/active_scaffold/data_structures/action_link.rb +4 -4
- data/lib/active_scaffold/data_structures/action_link.rb~ +179 -0
- data/lib/active_scaffold/data_structures/nested_info.rb~ +124 -0
- data/lib/active_scaffold/extensions/unsaved_associated.rb~ +62 -0
- data/lib/active_scaffold/finder.rb +9 -2
- data/lib/active_scaffold/finder.rb~ +11 -3
- data/lib/active_scaffold/helpers/list_column_helpers.rb +9 -6
- data/lib/active_scaffold/helpers/list_column_helpers.rb~ +9 -6
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/view_helpers.rb~ +3 -3
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold.rb +1 -1
- data/lib/active_scaffold.rb~ +362 -0
- metadata +17 -10
@@ -0,0 +1,179 @@
|
|
1
|
+
module ActiveScaffold::DataStructures
|
2
|
+
class ActionLink
|
3
|
+
# provides a quick way to set any property of the object from a hash
|
4
|
+
def initialize(action, options = {})
|
5
|
+
# set defaults
|
6
|
+
self.action = action.to_s
|
7
|
+
self.label = action
|
8
|
+
self.confirm = false
|
9
|
+
self.type = :collection
|
10
|
+
self.inline = true
|
11
|
+
self.method = :get
|
12
|
+
self.crud_type = :delete if [:destroy].include?(action.try(:to_sym))
|
13
|
+
self.crud_type = :create if [:create, :new].include?(action.try(:to_sym))
|
14
|
+
self.crud_type = :update if [:edit, :update].include?(action.try(:to_sym))
|
15
|
+
self.crud_type ||= :read
|
16
|
+
self.parameters = {}
|
17
|
+
self.html_options = {}
|
18
|
+
self.column = nil
|
19
|
+
self.image = nil
|
20
|
+
self.dynamic_parameters = nil
|
21
|
+
|
22
|
+
# apply quick properties
|
23
|
+
options.each_pair do |k, v|
|
24
|
+
setter = "#{k}="
|
25
|
+
self.send(setter, v) if self.respond_to? setter
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# the action-path for this link. what page to request? this is required!
|
30
|
+
attr_accessor :action
|
31
|
+
|
32
|
+
# the controller for this action link. if nil, the current controller should be assumed.
|
33
|
+
attr_writer :controller
|
34
|
+
|
35
|
+
def controller
|
36
|
+
@controller = @controller.call if @controller.is_a?(Proc)
|
37
|
+
@controller
|
38
|
+
end
|
39
|
+
|
40
|
+
def static_controller?
|
41
|
+
!(@controller.is_a?(Proc) || (@controller == :polymorph))
|
42
|
+
end
|
43
|
+
|
44
|
+
# a hash of request parameters
|
45
|
+
attr_accessor :parameters
|
46
|
+
|
47
|
+
# a block for dynamic_parameters
|
48
|
+
attr_accessor :dynamic_parameters
|
49
|
+
|
50
|
+
# the RESTful method
|
51
|
+
attr_accessor :method
|
52
|
+
|
53
|
+
# what string to use to represent this action
|
54
|
+
attr_writer :label
|
55
|
+
def label
|
56
|
+
@label.is_a?(Symbol) ? as_(@label) : @label
|
57
|
+
end
|
58
|
+
|
59
|
+
# image to use {:name => 'arrow.png', :size => '16x16'}
|
60
|
+
attr_accessor :image
|
61
|
+
|
62
|
+
# if the action requires confirmation
|
63
|
+
def confirm=(value)
|
64
|
+
@dhtml_confirm = nil if value
|
65
|
+
@confirm = value
|
66
|
+
end
|
67
|
+
def confirm(label = '')
|
68
|
+
@confirm.is_a?(String) ? @confirm : as_(@confirm, :label => label)
|
69
|
+
end
|
70
|
+
def confirm?
|
71
|
+
!!@confirm
|
72
|
+
end
|
73
|
+
|
74
|
+
# if the action uses a DHTML based (i.e. 2-phase) confirmation
|
75
|
+
attr_accessor :dhtml_confirm
|
76
|
+
def dhtml_confirm=(value)
|
77
|
+
@confirm = nil if value
|
78
|
+
@dhtml_confirm = value
|
79
|
+
end
|
80
|
+
def dhtml_confirm?
|
81
|
+
!!@dhtml_confirm
|
82
|
+
end
|
83
|
+
|
84
|
+
# what method to call on the controller to see if this action_link should be visible
|
85
|
+
# note that this is only the UI part of the security. to prevent URL hax0rz, you also need security on requests (e.g. don't execute update method unless authorized).
|
86
|
+
attr_writer :security_method
|
87
|
+
def security_method
|
88
|
+
@security_method || "#{self.action}_authorized?"
|
89
|
+
end
|
90
|
+
|
91
|
+
def security_method_set?
|
92
|
+
!!@security_method
|
93
|
+
end
|
94
|
+
|
95
|
+
attr_accessor :ignore_method
|
96
|
+
|
97
|
+
# the crud type of the (eventual?) action. different than :method, because this crud action may not be imminent.
|
98
|
+
# this is used to determine record-level authorization (e.g. record.authorized_for?(:crud_type => link.crud_type).
|
99
|
+
# options are :create, :read, :update, and :delete
|
100
|
+
attr_accessor :crud_type
|
101
|
+
|
102
|
+
# an "inline" link is inserted into the existing page
|
103
|
+
# exclusive with popup? and page?
|
104
|
+
def inline=(val)
|
105
|
+
@inline = (val == true)
|
106
|
+
self.popup = self.page = false if @inline
|
107
|
+
end
|
108
|
+
def inline?; @inline end
|
109
|
+
|
110
|
+
# a "popup" link displays in a separate (browser?) window. this will eventually take arguments.
|
111
|
+
# exclusive with inline? and page?
|
112
|
+
def popup=(val)
|
113
|
+
@popup = (val == true)
|
114
|
+
if @popup
|
115
|
+
self.inline = self.page = false
|
116
|
+
|
117
|
+
# the :method parameter doesn't mix with the :popup parameter
|
118
|
+
# when/if we start using DHTML popups, we can bring :method back
|
119
|
+
self.method = nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
def popup?; @popup end
|
123
|
+
|
124
|
+
# a "page" link displays by reloading the current page
|
125
|
+
# exclusive with inline? and popup?
|
126
|
+
def page=(val)
|
127
|
+
@page = (val == true)
|
128
|
+
if @page
|
129
|
+
self.inline = self.popup = false
|
130
|
+
|
131
|
+
# when :method is defined, ActionView adds an onclick to use a form ...
|
132
|
+
# so it's best to just empty out :method whenever possible.
|
133
|
+
# we only ever need to know @method = :get for things that default to POST.
|
134
|
+
# the only things that default to POST are forms and ajax calls.
|
135
|
+
# when @page = true, we don't use ajax.
|
136
|
+
self.method = nil if method == :get
|
137
|
+
end
|
138
|
+
end
|
139
|
+
def page?; @page end
|
140
|
+
|
141
|
+
# where the result of this action should insert in the display.
|
142
|
+
# for :type => :collection, supported values are:
|
143
|
+
# :top
|
144
|
+
# :bottom
|
145
|
+
# :replace (for updating the entire table)
|
146
|
+
# false (no attempt at positioning)
|
147
|
+
# for :type => :member, supported values are:
|
148
|
+
# :before
|
149
|
+
# :replace
|
150
|
+
# :after
|
151
|
+
# false (no attempt at positioning)
|
152
|
+
attr_writer :position
|
153
|
+
def position
|
154
|
+
return @position unless @position.nil? or @position == true
|
155
|
+
return :replace if self.type == :member
|
156
|
+
return :top if self.type == :collection
|
157
|
+
raise "what should the default position be for #{self.type}?"
|
158
|
+
end
|
159
|
+
|
160
|
+
# what type of link this is. currently supported values are :collection and :member.
|
161
|
+
attr_accessor :type
|
162
|
+
|
163
|
+
# html options for the link
|
164
|
+
attr_accessor :html_options
|
165
|
+
|
166
|
+
# nested action_links are referencing a column
|
167
|
+
attr_accessor :column
|
168
|
+
|
169
|
+
# indicates that this a nested_link
|
170
|
+
def nested_link?
|
171
|
+
@column || (parameters && parameters[:named_scope])
|
172
|
+
end
|
173
|
+
|
174
|
+
# Internal use: generated eid for this action_link
|
175
|
+
attr_accessor :eid
|
176
|
+
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module ActiveScaffold::DataStructures
|
2
|
+
class NestedInfo
|
3
|
+
def self.get(model, session_storage)
|
4
|
+
if session_storage[:nested].nil?
|
5
|
+
nil
|
6
|
+
else
|
7
|
+
session_info = session_storage[:nested].clone
|
8
|
+
begin
|
9
|
+
debugger
|
10
|
+
session_info[:parent_scaffold] = "#{session_info[:parent_scaffold].to_s.camelize}Controller".constantize
|
11
|
+
session_info[:parent_model] = session_info[:parent_scaffold].active_scaffold_config.model
|
12
|
+
session_info[:association] = session_info[:parent_model].reflect_on_association(session_info[:name])
|
13
|
+
unless session_info[:association].nil?
|
14
|
+
ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, session_info)
|
15
|
+
else
|
16
|
+
ActiveScaffold::DataStructures::NestedInfoScope.new(model, session_info)
|
17
|
+
end
|
18
|
+
rescue ActiveScaffold::ControllerNotFound
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :constrained_fields, :scope
|
25
|
+
|
26
|
+
def initialize(model, session_info)
|
27
|
+
@parent_model = session_info[:parent_model]
|
28
|
+
@parent_id = session_info[:parent_id]
|
29
|
+
@parent_scaffold = session_info[:parent_scaffold]
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_instance?
|
33
|
+
result = @new_instance.nil?
|
34
|
+
@new_instance = false
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def parent_scope
|
39
|
+
parent_model.find(parent_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
def habtm?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def belongs_to?
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_one?
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
def readonly?
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
def sorted?
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class NestedInfoAssociation < NestedInfo
|
64
|
+
def initialize(model, session_info)
|
65
|
+
super(model, session_info)
|
66
|
+
@association = session_info[:association]
|
67
|
+
iterate_model_associations(model)
|
68
|
+
end
|
69
|
+
|
70
|
+
def habtm?
|
71
|
+
association.macro == :has_and_belongs_to_many
|
72
|
+
end
|
73
|
+
|
74
|
+
def belongs_to?
|
75
|
+
association.belongs_to?
|
76
|
+
end
|
77
|
+
|
78
|
+
def has_one?
|
79
|
+
association.macro == :has_one
|
80
|
+
end
|
81
|
+
|
82
|
+
def readonly?
|
83
|
+
if association.options.has_key? :readonly
|
84
|
+
association.options[:readonly]
|
85
|
+
else
|
86
|
+
association.options.has_key? :through
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def sorted?
|
91
|
+
association.options.has_key? :order
|
92
|
+
end
|
93
|
+
|
94
|
+
def default_sorting
|
95
|
+
association.options[:order]
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def iterate_model_associations(model)
|
101
|
+
@constrained_fields = []
|
102
|
+
@constrained_fields << association.foreign_key.to_sym unless association.belongs_to?
|
103
|
+
model.reflect_on_all_associations.each do |current|
|
104
|
+
if !current.belongs_to? && association.foreign_key == current.association_foreign_key
|
105
|
+
constrained_fields << current.name.to_sym
|
106
|
+
@child_association = current if current.klass == @parent_model
|
107
|
+
end
|
108
|
+
if association.foreign_key == current.foreign_key
|
109
|
+
# show columns for has_many and has_one child associationes
|
110
|
+
constrained_fields << current.name.to_sym if current.belongs_to?
|
111
|
+
@child_association = current
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class NestedInfoScope < NestedInfo
|
118
|
+
def initialize(model, session_info)
|
119
|
+
super(model, session_info)
|
120
|
+
@scope = session_info[:name]
|
121
|
+
@constrained_fields = []
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# save and validation support for associations.
|
2
|
+
class ActiveRecord::Base
|
3
|
+
def associated_valid?(path = [])
|
4
|
+
return true if path.include?(self) # prevent recursion (if associated and parent are new records)
|
5
|
+
path << self
|
6
|
+
# using [].all? syntax to avoid a short-circuit
|
7
|
+
with_unsaved_associated { |a| debugger; [a.valid?, a.associated_valid?(path)].all? {|v| v == true} }
|
8
|
+
end
|
9
|
+
|
10
|
+
def save_associated
|
11
|
+
with_unsaved_associated { |a| a.save and a.save_associated }
|
12
|
+
end
|
13
|
+
|
14
|
+
def save_associated!
|
15
|
+
save_associated or raise(ActiveRecord::RecordNotSaved)
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_errors_in_associated?
|
19
|
+
with_unsaved_associated {|a| a.errors.count == 0 and a.no_errors_in_associated?}
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
# Provide an override to allow the model to restrict which associations are considered
|
25
|
+
# by ActiveScaffolds update mechanism. This allows the model to restrict things like
|
26
|
+
# Acts-As-Versioned versions associations being traversed.
|
27
|
+
#
|
28
|
+
# By defining the method :scaffold_update_nofollow returning an array of associations
|
29
|
+
# these associations will not be traversed.
|
30
|
+
# By defining the method :scaffold_update_follow returning an array of associations,
|
31
|
+
# only those associations will be traversed.
|
32
|
+
#
|
33
|
+
# Otherwise the default behaviour of traversing all associations will be preserved.
|
34
|
+
def associations_for_update
|
35
|
+
if self.respond_to?( :scaffold_update_nofollow )
|
36
|
+
self.class.reflect_on_all_associations.reject { |association| self.scaffold_update_nofollow.include?( association.name ) }
|
37
|
+
elsif self.respond_to?( :scaffold_update_follow )
|
38
|
+
self.class.reflect_on_all_associations.select { |association| self.scaffold_update_follow.include?( association.name ) }
|
39
|
+
else
|
40
|
+
self.class.reflect_on_all_associations
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# yields every associated object that has been instantiated and is flagged as unsaved.
|
47
|
+
# returns false if any yield returns false.
|
48
|
+
# returns true otherwise, even when none of the associations have been instantiated. build wrapper methods accordingly.
|
49
|
+
def with_unsaved_associated
|
50
|
+
associations_for_update.all? do |association|
|
51
|
+
association_proxy = send(association.name)
|
52
|
+
if association_proxy
|
53
|
+
records = association_proxy
|
54
|
+
records = [records] unless records.is_a? Array # convert singular associations into collections for ease of use
|
55
|
+
debugger
|
56
|
+
records.select {|r| r.unsaved? and not r.readonly?}.all? {|r| yield r} # must use select instead of find_all, which Rails overrides on association proxies for db access
|
57
|
+
else
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -108,11 +108,18 @@ module ActiveScaffold
|
|
108
108
|
|
109
109
|
def condition_value_for_datetime(value, conversion = :to_time)
|
110
110
|
if value.is_a? Hash
|
111
|
-
Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect {|part| value[
|
111
|
+
Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect {|part| value[part].to_i}) rescue nil
|
112
112
|
elsif value.respond_to?(:strftime)
|
113
113
|
value.send(conversion)
|
114
|
+
elsif conversion == :to_date
|
115
|
+
Date.strptime(value, I18n.t('date.formats.default')) rescue nil
|
114
116
|
else
|
115
|
-
|
117
|
+
parts = Date._parse(value)
|
118
|
+
time_parts = [[:hour, '%H'], [:min, '%M'], [:sec, '%S']].collect {|part, format_part| format_part if parts[part].present?}.compact
|
119
|
+
format = "#{I18n.t('date.formats.default')} #{time_parts.join(':')} #{'%z' if parts[:offset].present?}"
|
120
|
+
time = DateTime.strptime(value, format)
|
121
|
+
time = Time.zone.local_to_utc(time) unless parts[:offset]
|
122
|
+
time.in_time_zone.send(conversion) rescue nil
|
116
123
|
end unless value.nil? || value.blank?
|
117
124
|
end
|
118
125
|
|
@@ -108,11 +108,18 @@ module ActiveScaffold
|
|
108
108
|
|
109
109
|
def condition_value_for_datetime(value, conversion = :to_time)
|
110
110
|
if value.is_a? Hash
|
111
|
-
Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect {|part| value[
|
111
|
+
Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect {|part| value[part].to_i}) rescue nil
|
112
112
|
elsif value.respond_to?(:strftime)
|
113
113
|
value.send(conversion)
|
114
|
+
elsif conversion == :to_date
|
115
|
+
Date.strptime(value, I18n.t('date.formats.default')) rescue nil
|
114
116
|
else
|
115
|
-
|
117
|
+
parts = Date._parse(value)
|
118
|
+
time_parts = [[:hour, '%H'], [:min, '%M'], [:sec, '%S']].collect {|part, format_part| format_part if parts[part].present?}.compact
|
119
|
+
format = "#{I18n.t('date.formats.default')} #{time_parts.join(':')} #{'%z' if parts[:offset].present?}"
|
120
|
+
time = DateTime.strptime(value, format)
|
121
|
+
time = Time.zone.local_to_utc(time) unless parts[:offset]
|
122
|
+
time.in_time_zone.send(conversion) rescue nil
|
116
123
|
end unless value.nil? || value.blank?
|
117
124
|
end
|
118
125
|
|
@@ -270,7 +277,7 @@ module ActiveScaffold
|
|
270
277
|
# Returns a hash with options to count records, rejecting select and order options
|
271
278
|
# See finder_options for valid options
|
272
279
|
def count_options(find_options = {}, count_includes = nil)
|
273
|
-
count_includes ||= find_options[:includes] unless find_options[:
|
280
|
+
count_includes ||= find_options[:includes] unless find_options[:where].nil?
|
274
281
|
options = find_options.reject{|k,v| [:select, :order].include? k}
|
275
282
|
options[:includes] = count_includes
|
276
283
|
options
|
@@ -289,6 +296,7 @@ module ActiveScaffold
|
|
289
296
|
# NOTE: we must use :include in the count query, because some conditions may reference other tables
|
290
297
|
if options[:pagination] && options[:pagination] != :infinite
|
291
298
|
count_query = append_to_query(klass, count_options(find_options, options[:count_includes]))
|
299
|
+
debugger
|
292
300
|
count = count_query.count unless options[:pagination] == :infinite
|
293
301
|
end
|
294
302
|
|
@@ -34,13 +34,14 @@ module ActiveScaffold
|
|
34
34
|
if column.link
|
35
35
|
link = column.link
|
36
36
|
associated = record.send(column.association.name) if column.association
|
37
|
-
url_options = params_for(:action => nil, :id => record.id
|
37
|
+
url_options = params_for(:action => nil, :id => record.id)
|
38
38
|
|
39
39
|
# setup automatic link
|
40
40
|
if column.autolink? && column.singular_association? # link to inline form
|
41
|
-
link = action_link_to_inline_form(column, record, associated)
|
42
|
-
return text if link.
|
43
|
-
|
41
|
+
link = action_link_to_inline_form(column, record, associated, text)
|
42
|
+
return text if link.nil?
|
43
|
+
else
|
44
|
+
url_options[:link] = text
|
44
45
|
end
|
45
46
|
|
46
47
|
if column_link_authorized?(link, column, record, associated)
|
@@ -55,8 +56,9 @@ module ActiveScaffold
|
|
55
56
|
end
|
56
57
|
|
57
58
|
# setup the action link to inline form
|
58
|
-
def action_link_to_inline_form(column, record, associated)
|
59
|
+
def action_link_to_inline_form(column, record, associated, text)
|
59
60
|
link = column.link.clone
|
61
|
+
link.label = text
|
60
62
|
if column.polymorphic_association?
|
61
63
|
polymorphic_controller = controller_path_for_activerecord(record.send(column.association.name).class)
|
62
64
|
return link if polymorphic_controller.nil?
|
@@ -70,6 +72,7 @@ module ActiveScaffold
|
|
70
72
|
if actions.include?(:new)
|
71
73
|
link.action = 'new'
|
72
74
|
link.crud_type = :create
|
75
|
+
link.label = as_(:create_new)
|
73
76
|
end
|
74
77
|
elsif actions.include?(:edit)
|
75
78
|
link.action = 'edit'
|
@@ -81,7 +84,7 @@ module ActiveScaffold
|
|
81
84
|
link.action = 'index'
|
82
85
|
link.crud_type = :read
|
83
86
|
end
|
84
|
-
link
|
87
|
+
link if link.action.present?
|
85
88
|
end
|
86
89
|
|
87
90
|
def column_link_authorized?(link, column, record, associated)
|
@@ -34,13 +34,14 @@ module ActiveScaffold
|
|
34
34
|
if column.link
|
35
35
|
link = column.link
|
36
36
|
associated = record.send(column.association.name) if column.association
|
37
|
-
url_options = params_for(:action => nil, :id => record.id
|
37
|
+
url_options = params_for(:action => nil, :id => record.id)
|
38
38
|
|
39
39
|
# setup automatic link
|
40
40
|
if column.autolink? && column.singular_association? # link to inline form
|
41
|
-
link = action_link_to_inline_form(column, record, associated)
|
42
|
-
return text if link.
|
43
|
-
|
41
|
+
link = action_link_to_inline_form(column, record, associated, text)
|
42
|
+
return text if link.nil?
|
43
|
+
else
|
44
|
+
url_options[:link] = text
|
44
45
|
end
|
45
46
|
|
46
47
|
if column_link_authorized?(link, column, record, associated)
|
@@ -55,8 +56,9 @@ module ActiveScaffold
|
|
55
56
|
end
|
56
57
|
|
57
58
|
# setup the action link to inline form
|
58
|
-
def action_link_to_inline_form(column, record, associated)
|
59
|
+
def action_link_to_inline_form(column, record, associated, text)
|
59
60
|
link = column.link.clone
|
61
|
+
link.label = text
|
60
62
|
if column.polymorphic_association?
|
61
63
|
polymorphic_controller = controller_path_for_activerecord(record.send(column.association.name).class)
|
62
64
|
return link if polymorphic_controller.nil?
|
@@ -70,6 +72,7 @@ module ActiveScaffold
|
|
70
72
|
if actions.include?(:new)
|
71
73
|
link.action = 'new'
|
72
74
|
link.crud_type = :create
|
75
|
+
link.label = as_(:create_new)
|
73
76
|
end
|
74
77
|
elsif actions.include?(:edit)
|
75
78
|
link.action = 'edit'
|
@@ -81,7 +84,7 @@ module ActiveScaffold
|
|
81
84
|
link.action = 'index'
|
82
85
|
link.crud_type = :read
|
83
86
|
end
|
84
|
-
link
|
87
|
+
link if link.crud_type.present?
|
85
88
|
end
|
86
89
|
|
87
90
|
def column_link_authorized?(link, column, record, associated)
|
@@ -134,7 +134,7 @@ module ActiveScaffold
|
|
134
134
|
|
135
135
|
def action_link_html_options(link, url_options, record, html_options)
|
136
136
|
link_id = get_action_link_id(url_options, record, link.column)
|
137
|
-
html_options.reverse_merge! link.html_options.merge(:class => link.action)
|
137
|
+
html_options.reverse_merge! link.html_options.merge(:class => link.action.to_s)
|
138
138
|
|
139
139
|
# Needs to be in html_options to as the adding _method to the url is no longer supported by Rails
|
140
140
|
html_options[:method] = link.method if link.method != :get
|
@@ -70,7 +70,7 @@ module ActiveScaffold
|
|
70
70
|
return false if column.polymorphic_association?
|
71
71
|
|
72
72
|
# A column shouldn't be in the subform if it's the reverse association to the parent
|
73
|
-
return false if column.association.
|
73
|
+
return false if column.association.inverse_for?(parent_record.class)
|
74
74
|
|
75
75
|
return true
|
76
76
|
end
|
@@ -134,7 +134,7 @@ module ActiveScaffold
|
|
134
134
|
|
135
135
|
def action_link_html_options(link, url_options, record, html_options)
|
136
136
|
link_id = get_action_link_id(url_options, record, link.column)
|
137
|
-
html_options.reverse_merge! link.html_options.merge(:class => link.action)
|
137
|
+
html_options.reverse_merge! link.html_options.merge(:class => link.action.to_s)
|
138
138
|
|
139
139
|
# Needs to be in html_options to as the adding _method to the url is no longer supported by Rails
|
140
140
|
html_options[:method] = link.method if link.method != :get
|
@@ -194,7 +194,7 @@ module ActiveScaffold
|
|
194
194
|
url_options[:eid] = link.eid
|
195
195
|
elsif link.parameters && link.parameters[:named_scope]
|
196
196
|
url_options[:assoc_id] = url_options.delete(:id)
|
197
|
-
link.eid = "#{controller_id.from(3)}_#{record.id}_#{link.parameters[:named_scope]}" unless options.has_key?(:reuse_eid)
|
197
|
+
link.eid = "#{controller_id.from(3)}_#{record.id}_#{link.parameters[:named_scope]}" unless record.nil? || options.has_key?(:reuse_eid)
|
198
198
|
url_options[:eid] = link.eid
|
199
199
|
end
|
200
200
|
end
|
data/lib/active_scaffold.rb
CHANGED
@@ -266,7 +266,7 @@ module ActiveScaffold
|
|
266
266
|
column.actions_for_association_links.delete :new unless actions.include? :create
|
267
267
|
column.actions_for_association_links.delete :edit unless actions.include? :update
|
268
268
|
column.actions_for_association_links.delete :show unless actions.include? :show
|
269
|
-
ActiveScaffold::DataStructures::ActionLink.new(
|
269
|
+
ActiveScaffold::DataStructures::ActionLink.new(nil, options.merge(:html_options => {:class => column.name}))
|
270
270
|
end
|
271
271
|
end
|
272
272
|
end
|