active_scaffold 3.1.4 → 3.1.5

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