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.
@@ -82,8 +82,12 @@ module ActiveScaffold::Actions
82
82
  end
83
83
 
84
84
  def beginning_of_chain
85
- if nested? && nested.association && nested.association.collection?
86
- nested.parent_scope.send(nested.association.name)
85
+ if nested? && nested.association && !nested.association.belongs_to?
86
+ if nested.association.collection?
87
+ nested.parent_scope.send(nested.association.name)
88
+ elsif nested.child_association.belongs_to?
89
+ active_scaffold_config.model.where(nested.child_association.foreign_key => nested.parent_scope)
90
+ end
87
91
  elsif nested? && nested.scope
88
92
  nested.parent_scope.send(nested.scope)
89
93
  else
@@ -82,8 +82,13 @@ module ActiveScaffold::Actions
82
82
  end
83
83
 
84
84
  def beginning_of_chain
85
- if nested? && nested.association && nested.association.collection?
86
- nested.parent_scope.send(nested.association.name)
85
+ if nested? && nested.association && !nested.association.belongs_to?
86
+ debugger
87
+ if nested.association.collection?
88
+ nested.parent_scope.send(nested.association.name)
89
+ elsif nested.child_association.belongs_to?
90
+ active_scaffold_config.model.where(nested.child_association.foreign_key => nested.parent_scope)
91
+ end
87
92
  elsif nested? && nested.scope
88
93
  nested.parent_scope.send(nested.scope)
89
94
  else
@@ -123,9 +128,6 @@ module ActiveScaffold::Actions::Nested
123
128
 
124
129
  def self.included(base)
125
130
  super
126
- base.verify :method => :post,
127
- :only => :add_existing,
128
- :redirect_to => { :action => :index }
129
131
  end
130
132
 
131
133
  def new_existing
@@ -32,8 +32,7 @@ module ActiveScaffold::Actions
32
32
  def edit_respond_to_js
33
33
  render(:partial => 'update_form')
34
34
  end
35
- def update_respond_to_html
36
- debugger
35
+ def update_respond_to_html
37
36
  if params[:iframe]=='true' # was this an iframe post ?
38
37
  responds_to_parent do
39
38
  render :action => 'on_update.js', :layout => false
@@ -48,7 +47,6 @@ module ActiveScaffold::Actions
48
47
  end
49
48
  end
50
49
  def update_respond_to_js
51
- debugger
52
50
  if successful? && update_refresh_list? && !render_parent?
53
51
  do_search if respond_to? :do_search
54
52
  do_list
@@ -84,6 +82,7 @@ module ActiveScaffold::Actions
84
82
  @record = update_record_from_params(@record, active_scaffold_config.update.columns, params[:record]) unless options[:no_record_param_update]
85
83
  before_update_save(@record)
86
84
  self.successful = [@record.valid?, @record.associated_valid?].all? {|v| v == true} # this syntax avoids a short-circuit
85
+ debugger
87
86
  if successful?
88
87
  @record.save! and @record.save_associated!
89
88
  after_update_save(@record)
@@ -0,0 +1,209 @@
1
+ module ActiveScaffold
2
+ module Bridges
3
+ module Shared
4
+ module DateBridge
5
+ module SearchColumnHelpers
6
+ def active_scaffold_search_date_bridge(column, options)
7
+ current_search = {'from' => nil, 'to' => nil, 'opt' => 'BETWEEN',
8
+ 'number' => 1, 'unit' => 'DAYS', 'range' => nil}
9
+ current_search.merge!(options[:value]) unless options[:value].nil?
10
+ tags = []
11
+ tags << active_scaffold_search_date_bridge_comparator_tag(column, options, current_search)
12
+ tags << active_scaffold_search_date_bridge_trend_tag(column, options, current_search)
13
+ tags << active_scaffold_search_date_bridge_numeric_tag(column, options, current_search)
14
+ tags << active_scaffold_search_date_bridge_range_tag(column, options, current_search)
15
+ tags.join("&nbsp;").html_safe
16
+ end
17
+
18
+ def active_scaffold_search_date_bridge_comparator_options(column)
19
+ select_options = ActiveScaffold::Finder::DateComparators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
20
+ select_options + ActiveScaffold::Finder::NumericComparators.collect {|comp| [as_(comp.downcase.to_sym), comp]}
21
+ end
22
+
23
+ def active_scaffold_search_date_bridge_comparator_tag(column, options, current_search)
24
+ select_tag("#{options[:name]}[opt]", options_for_select(active_scaffold_search_date_bridge_comparator_options(column),current_search['opt']), :id => "#{options[:id]}_opt", :class => "as_search_range_option as_search_date_time_option")
25
+ end
26
+
27
+ def active_scaffold_search_date_bridge_numeric_tag(column, options, current_search)
28
+ numeric_controls = "" <<
29
+ active_scaffold_search_date_bridge_calendar_control(column, options, current_search, 'from') <<
30
+ content_tag(:span, (" - " + active_scaffold_search_date_bridge_calendar_control(column, options, current_search, 'to')).html_safe,
31
+ :id => "#{options[:id]}_between", :class => "as_search_range_between", :style => "display:#{current_search['opt'] == 'BETWEEN' ? '' : 'none'}")
32
+ content_tag("span", numeric_controls.html_safe, :id => "#{options[:id]}_numeric", :style => "display:#{ActiveScaffold::Finder::NumericComparators.include?(current_search['opt']) ? '' : 'none'}")
33
+ end
34
+
35
+ def active_scaffold_search_date_bridge_trend_tag(column, options, current_search)
36
+ active_scaffold_date_bridge_trend_tag(column, options,
37
+ {:name_prefix => 'search',
38
+ :number_value => current_search['number'],
39
+ :unit_value => current_search["unit"],
40
+ :show => (current_search['opt'] == 'PAST' || current_search['opt'] == 'FUTURE')})
41
+ end
42
+
43
+ def active_scaffold_date_bridge_trend_tag(column, options, trend_options)
44
+ trend_controls = text_field_tag("#{trend_options[:name_prefix]}[#{column.name}][number]", trend_options[:number_value], :class => 'text-input', :size => 10, :autocomplete => 'off') << " " <<
45
+ select_tag("#{trend_options[:name_prefix]}[#{column.name}][unit]",
46
+ options_for_select(active_scaffold_search_date_bridge_trend_units(column), trend_options[:unit_value]),
47
+ :class => 'text-input')
48
+ content_tag("span", trend_controls.html_safe, :id => "#{options[:id]}_trend", :style => "display:#{trend_options[:show] ? '' : 'none'}")
49
+ end
50
+
51
+ def active_scaffold_search_date_bridge_trend_units(column)
52
+ options = ActiveScaffold::Finder::DateUnits.collect{|unit| [as_(unit.downcase.to_sym), unit]}
53
+ options = ActiveScaffold::Finder::TimeUnits.collect{|unit| [as_(unit.downcase.to_sym), unit]} + options if column_datetime?(column)
54
+ options
55
+ end
56
+
57
+ def active_scaffold_search_date_bridge_range_tag(column, options, current_search)
58
+ range_controls = select_tag("search[#{column.name}][range]",
59
+ options_for_select( ActiveScaffold::Finder::DateRanges.collect{|range| [as_(range.downcase.to_sym), range]}, current_search["range"]),
60
+ :class => 'text-input')
61
+ content_tag("span", range_controls.html_safe, :id => "#{options[:id]}_range", :style => "display:#{(current_search['opt'] == 'RANGE') ? '' : 'none'}")
62
+ end
63
+
64
+ def column_datetime?(column)
65
+ (!column.column.nil? && [:datetime, :time].include?(column.column.type))
66
+ end
67
+ end
68
+
69
+ module HumanConditionHelpers
70
+ def active_scaffold_human_condition_date_bridge(column, value)
71
+ case value[:opt]
72
+ when 'RANGE'
73
+ range_type, range = value[:range].downcase.split('_')
74
+ format = active_scaffold_human_condition_date_bridge_range_format(range_type, range)
75
+ from, to = controller.class.date_bridge_from_to(column, value)
76
+ "#{column.active_record_class.human_attribute_name(column.name)} = #{as_(value[:range].downcase).downcase} (#{I18n.l(from, :format => format)})"
77
+ when 'PAST', 'FUTURE'
78
+ from, to = controller.class.date_bridge_from_to(column, value)
79
+ "#{column.active_record_class.human_attribute_name(column.name)} #{as_('BETWEEN'.downcase).downcase} #{I18n.l(from)} - #{I18n.l(to)}"
80
+ else
81
+ from, to = controller.class.date_bridge_from_to(column, value)
82
+ "#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt].downcase).downcase} #{I18n.l(from)} #{value[:opt] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
83
+ end
84
+ end
85
+
86
+ def active_scaffold_human_condition_date_bridge_range_format(range_type, range)
87
+ case range
88
+ when 'week'
89
+ first_day_of_week = I18n.translate 'active_scaffold.date_picker_options.firstDay'
90
+ if first_day_of_week == 1
91
+ '%W %Y'
92
+ else
93
+ '%U %Y'
94
+ end
95
+ when 'month'
96
+ '%b %Y'
97
+ when 'year'
98
+ '%Y'
99
+ else
100
+ I18n.translate 'date.formats.default'
101
+ end
102
+ end
103
+ end
104
+
105
+ module Finder
106
+ module ClassMethods
107
+ def condition_for_date_bridge_type(column, value, like_pattern)
108
+ operator = ActiveScaffold::Finder::NumericComparators.include?(value[:opt]) && value[:opt] != 'BETWEEN' ? value[:opt] : nil
109
+ from_value, to_value = date_bridge_from_to(column, value)
110
+
111
+ if column.search_sql.is_a? Proc
112
+ column.search_sql.call(from_value, to_value, operator)
113
+ else
114
+ unless operator.nil?
115
+ ["#{column.search_sql} #{value[:opt]} ?", from_value.to_s(:db)] unless from_value.nil?
116
+ else
117
+ ["#{column.search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)] unless from_value.nil? && to_value.nil?
118
+ end
119
+ end
120
+ end
121
+
122
+ def date_bridge_from_to(column, value)
123
+ conversion = column.column.type == :date ? :to_date : :to_time
124
+ case value[:opt]
125
+ when 'RANGE'
126
+ date_bridge_from_to_for_range(column, value).collect(&conversion)
127
+ when 'PAST', 'FUTURE'
128
+ date_bridge_from_to_for_trend(column, value).collect(&conversion)
129
+ else
130
+ ['from', 'to'].collect { |field| condition_value_for_datetime(value[field], conversion)}
131
+ end
132
+ end
133
+
134
+ def date_bridge_now
135
+ Time.zone.now
136
+ end
137
+
138
+ def date_bridge_from_to_for_trend(column, value)
139
+ case value['opt']
140
+ when "PAST"
141
+ trend_number = [value['number'].to_i, 1].max
142
+ now = date_bridge_now
143
+ if date_bridge_column_date?(column)
144
+ from = now.beginning_of_day.ago((trend_number).send(value['unit'].downcase.singularize.to_sym))
145
+ to = now.end_of_day
146
+ else
147
+ from = now.ago((trend_number).send(value['unit'].downcase.singularize.to_sym))
148
+ to = now
149
+ end
150
+ return from, to
151
+ when "FUTURE"
152
+ trend_number = [value['number'].to_i, 1].max
153
+ now = date_bridge_now
154
+ if date_bridge_column_date?(column)
155
+ from = now.beginning_of_day
156
+ to = now.end_of_day.in((trend_number).send(value['unit'].downcase.singularize.to_sym))
157
+ else
158
+ from = now
159
+ to = now.in((trend_number).send(value['unit'].downcase.singularize.to_sym))
160
+ end
161
+ return from, to
162
+ end
163
+ end
164
+
165
+ def date_bridge_from_to_for_range(column, value)
166
+ case value[:range]
167
+ when 'TODAY'
168
+ return date_bridge_now.beginning_of_day, date_bridge_now.end_of_day
169
+ when 'YESTERDAY'
170
+ return date_bridge_now.ago(1.day).beginning_of_day, date_bridge_now.ago(1.day).end_of_day
171
+ when 'TOMORROW'
172
+ return date_bridge_now.in(1.day).beginning_of_day, date_bridge_now.in(1.day).end_of_day
173
+ else
174
+ range_type, range = value[:range].downcase.split('_')
175
+ raise ArgumentError unless ['week', 'month', 'year'].include?(range)
176
+ case range_type
177
+ when 'this'
178
+ return date_bridge_now.send("beginning_of_#{range}".to_sym), date_bridge_now.send("end_of_#{range}")
179
+ when 'prev'
180
+ return date_bridge_now.ago(1.send(range.to_sym)).send("beginning_of_#{range}".to_sym), date_bridge_now.ago(1.send(range.to_sym)).send("end_of_#{range}".to_sym)
181
+ when 'next'
182
+ return date_bridge_now.in(1.send(range.to_sym)).send("beginning_of_#{range}".to_sym), date_bridge_now.in(1.send(range.to_sym)).send("end_of_#{range}".to_sym)
183
+ else
184
+ return nil, nil
185
+ end
186
+ end
187
+ end
188
+
189
+ def date_bridge_column_date?(column)
190
+ if [:date_picker, :datetime_picker].include? column.form_ui
191
+ column.form_ui == :date_picker
192
+ else
193
+ (!column.column.nil? && [:date].include?(column.column.type))
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ ActiveScaffold::Finder.const_set('DateComparators', ["PAST", "FUTURE", "RANGE"])
204
+ ActiveScaffold::Finder.const_set('DateUnits', ["DAYS", "WEEKS", "MONTHS", "YEARS"])
205
+ ActiveScaffold::Finder.const_set('TimeUnits', ["SECONDS", "MINUTES", "HOURS"])
206
+ ActiveScaffold::Finder.const_set('DateRanges', ["TODAY", "YESTERDAY", "TOMORROW",
207
+ "THIS_WEEK", "PREV_WEEK", "NEXT_WEEK",
208
+ "THIS_MONTH", "PREV_MONTH", "NEXT_MONTH",
209
+ "THIS_YEAR", "PREV_YEAR", "NEXT_YEAR"])
@@ -24,6 +24,7 @@ module ActiveScaffold::Config
24
24
  unless column.nil? || column.association.nil?
25
25
  options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => 2, :default => column.association.klass.name.pluralize})
26
26
  action_link = @core.link_for_association(column, options)
27
+ action_link.action ||= :index
27
28
  @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
28
29
  else
29
30
 
@@ -0,0 +1,41 @@
1
+ module ActiveScaffold::Config
2
+ class Nested < Base
3
+ self.crud_type = :read
4
+
5
+ def initialize(core_config)
6
+ super
7
+ @label = :add_existing_model
8
+ self.shallow_delete = self.class.shallow_delete
9
+ @action_group = self.class.action_group.clone if self.class.action_group
10
+ end
11
+
12
+ # global level configuration
13
+ # --------------------------
14
+ cattr_accessor :shallow_delete
15
+ @@shallow_delete = true
16
+
17
+ # instance-level configuration
18
+ # ----------------------------
19
+ attr_accessor :shallow_delete
20
+
21
+ # Add a nested ActionLink
22
+ def add_link(attribute, options = {})
23
+ column = @core.columns[attribute.to_sym]
24
+ unless column.nil? || column.association.nil?
25
+ options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => 2, :default => column.association.klass.name.pluralize})
26
+ action_link = @core.link_for_association(column, options)
27
+ @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
28
+ else
29
+
30
+ end
31
+ end
32
+
33
+ def add_scoped_link(named_scope, options = {})
34
+ action_link = @core.link_for_association_as_scope(named_scope.to_sym, options)
35
+ @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
36
+ end
37
+
38
+ # the label for this Nested action. used for the header.
39
+ attr_writer :label
40
+ end
41
+ end
@@ -0,0 +1,186 @@
1
+ module ActiveScaffold
2
+ module Constraints
3
+
4
+ protected
5
+
6
+ # Returns the current constraints
7
+ def active_scaffold_constraints
8
+ @active_scaffold_constraints ||= active_scaffold_session_storage[:constraints] || {}
9
+ end
10
+
11
+ def set_active_scaffold_constraints
12
+ associations_by_params = {}
13
+ active_scaffold_config.model.reflect_on_all_associations.each do |association|
14
+ associations_by_params[association.klass.name.foreign_key] = association.name unless association.options[:polymorphic]
15
+ end
16
+ params.each do |key, value|
17
+ active_scaffold_constraints[associations_by_params[key]] = value if associations_by_params.include? key
18
+ end
19
+ end
20
+
21
+ # For each enabled action, adds the constrained columns to the ActionColumns object (if it exists).
22
+ # This lets the ActionColumns object skip constrained columns.
23
+ #
24
+ # If the constraint value is a Hash, then we assume the constraint is a multi-level association constraint (the reverse of a has_many :through) and we do NOT register the constraint column.
25
+ def register_constraints_with_action_columns(association_constrained_fields = [], exclude_actions = [])
26
+ debugger
27
+ constrained_fields = active_scaffold_constraints.reject{|k, v| v.is_a? Hash}.keys.collect{|k| k.to_sym}
28
+ constrained_fields = constrained_fields | association_constrained_fields
29
+ if self.class.uses_active_scaffold?
30
+ # we actually want to do this whether constrained_fields exist or not, so that we can reset the array when they don't
31
+ active_scaffold_config.actions.each do |action_name|
32
+ next if exclude_actions.include?(action_name)
33
+ action = active_scaffold_config.send(action_name)
34
+ next unless action.respond_to? :columns
35
+ action.columns.constraint_columns = constrained_fields
36
+ end
37
+ end
38
+ end
39
+
40
+ # Returns search conditions based on the current scaffold constraints.
41
+ #
42
+ # Supports constraints based on either a column name (in which case it checks for an association
43
+ # or just uses the search_sql) or a database field name.
44
+ #
45
+ # All of this work is primarily to support nested scaffolds in a manner generally useful for other
46
+ # embedded scaffolds.
47
+ def conditions_from_constraints
48
+ conditions = nil
49
+ debugger
50
+ active_scaffold_constraints.each do |k, v|
51
+ column = active_scaffold_config.columns[k]
52
+ constraint_condition = if column
53
+ # Assume this is a multi-level association constraint.
54
+ # example:
55
+ # data model: Park -> Den -> Bear
56
+ # constraint: :den => {:park => 5}
57
+ if v.is_a? Hash
58
+ far_association = column.association.klass.reflect_on_association(v.keys.first)
59
+ field = far_association.klass.primary_key
60
+ table = far_association.table_name
61
+
62
+ active_scaffold_includes.concat([{k => v.keys.first}]) # e.g. {:den => :park}
63
+ constraint_condition_for("#{table}.#{field}", v.values.first)
64
+
65
+ # association column constraint
66
+ elsif column.association
67
+ if column.association.macro == :has_and_belongs_to_many
68
+ active_scaffold_habtm_joins.concat column.includes
69
+ else
70
+ active_scaffold_includes.concat column.includes
71
+ end
72
+ condition_from_association_constraint(column.association, v)
73
+
74
+ # regular column constraints
75
+ elsif column.searchable?
76
+ active_scaffold_includes.concat column.includes
77
+ constraint_condition_for(column.search_sql, v)
78
+ end
79
+ # unknown-to-activescaffold-but-real-database-column constraint
80
+ elsif active_scaffold_config.model.column_names.include? k.to_s
81
+ constraint_condition_for(k.to_s, v)
82
+ else
83
+ raise ActiveScaffold::MalformedConstraint, constraint_error(active_scaffold_config.model, k), caller
84
+ end
85
+
86
+ conditions = merge_conditions(conditions, constraint_condition)
87
+ end
88
+
89
+ conditions
90
+ end
91
+
92
+ # We do NOT want to use .search_sql. If anything, search_sql will refer
93
+ # to a human-searchable value on the associated record.
94
+ def condition_from_association_constraint(association, value)
95
+ # when the reverse association is a :belongs_to, the id for the associated object only exists as
96
+ # the primary_key on the other table. so for :has_one and :has_many (when the reverse is :belongs_to),
97
+ # we have to use the other model's primary_key.
98
+ #
99
+ # please see the relevant tests for concrete examples.
100
+ field = if [:has_one, :has_many].include?(association.macro)
101
+ association.klass.primary_key
102
+ elsif [:has_and_belongs_to_many].include?(association.macro)
103
+ association.association_foreign_key
104
+ else
105
+ association.options[:foreign_key] || association.name.to_s.foreign_key
106
+ end
107
+
108
+ table = case association.macro
109
+ when :has_and_belongs_to_many
110
+ association.options[:join_table]
111
+
112
+ when :belongs_to
113
+ active_scaffold_config.model.table_name
114
+
115
+ else
116
+ association.table_name
117
+ end
118
+
119
+ if association.options[:primary_key]
120
+ value = association.klass.find(value).send(association.options[:primary_key])
121
+ end
122
+
123
+ condition = constraint_condition_for("#{table}.#{field}", value)
124
+ if association.options[:polymorphic]
125
+ begin
126
+ parent_scaffold = "#{session_info[:parent_scaffold].to_s.camelize}Controller".constantize
127
+ condition = merge_conditions(
128
+ condition,
129
+ constraint_condition_for("#{table}.#{association.name}_type", parent_scaffold.active_scaffold_config.model_id.to_s)
130
+ )
131
+ rescue ActiveScaffold::ControllerNotFound
132
+ nil
133
+ end
134
+ end
135
+
136
+ condition
137
+ end
138
+
139
+ def constraint_error(klass, column_name)
140
+ "Malformed constraint `#{klass}##{column_name}'. If it's a legitimate column, and you are using a nested scaffold, please specify or double-check the reverse association name."
141
+ end
142
+
143
+ # Applies constraints to the given record.
144
+ #
145
+ # Searches through the known columns for association columns. If the given constraint is an association,
146
+ # it assumes that the constraint value is an id. It then does a association.klass.find with the value
147
+ # and adds the associated object to the record.
148
+ #
149
+ # For some operations ActiveRecord will automatically update the database. That's not always ok.
150
+ # If it *is* ok (e.g. you're in a transaction), then set :allow_autosave to true.
151
+ def apply_constraints_to_record(record, options = {})
152
+ options[:allow_autosave] = false if options[:allow_autosave].nil?
153
+
154
+ active_scaffold_constraints.each do |k, v|
155
+ column = active_scaffold_config.columns[k]
156
+ if column and column.association
157
+ if column.plural_association?
158
+ record.send("#{k}").send(:<<, column.association.klass.find(v))
159
+ elsif column.association.options[:polymorphic]
160
+ record.send("#{k}=", params[:parent_model].constantize.find(v))
161
+ else # regular singular association
162
+ record.send("#{k}=", column.association.klass.find(v))
163
+
164
+ # setting the belongs_to side of a has_one isn't safe. if the has_one was already
165
+ # specified, rails won't automatically clear out the previous associated record.
166
+ #
167
+ # note that we can't take the extra step to correct this unless we're permitted to
168
+ # run operations where activerecord auto-saves the object.
169
+ reverse = column.association.klass.reflect_on_association(column.association.reverse)
170
+ if reverse.macro == :has_one and options[:allow_autosave]
171
+ record.send(k).send("#{column.association.reverse}=", record)
172
+ end
173
+ end
174
+ else
175
+ record.send("#{k}=", v)
176
+ end
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ def constraint_condition_for(sql, value)
183
+ value.nil? ? "#{sql} IS NULL" : ["#{sql} = ?", value]
184
+ end
185
+ end
186
+ end
@@ -3,15 +3,15 @@ module ActiveScaffold::DataStructures
3
3
  # provides a quick way to set any property of the object from a hash
4
4
  def initialize(action, options = {})
5
5
  # set defaults
6
- self.action = action.to_s
6
+ self.action = action
7
7
  self.label = action
8
8
  self.confirm = false
9
9
  self.type = :collection
10
10
  self.inline = true
11
11
  self.method = :get
12
- self.crud_type = :delete if [:destroy].include?(action.to_sym)
13
- self.crud_type = :create if [:create, :new].include?(action.to_sym)
14
- self.crud_type = :update if [:edit, :update].include?(action.to_sym)
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
15
  self.crud_type ||= :read
16
16
  self.parameters = {}
17
17
  self.html_options = {}