active_scaffold 3.4.11 → 3.4.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e19f95fd4ac370c29a8d8774e4b3c94083e6df2a
4
- data.tar.gz: 419230d149a695aebf92be0aa1d6c1455868ddac
3
+ metadata.gz: 3e90634abde41880d285eb02b74524c356bb44ba
4
+ data.tar.gz: 10e6bd5dcdd6ca95f8bbfc43cb6b65e6a162293e
5
5
  SHA512:
6
- metadata.gz: d763e9f014fc3b43cfa5f81218d50a5f4f276d56f97522c1631c7771ad9ae6793318ee9b112dc691d73f80541b4a39ab73b8ba6e6f7413fcab4b15510c66c66b
7
- data.tar.gz: 77add87ef5f5ce6260296e9272fdae39de94407ff9071fdd3250f5f7219262660a2485889dc6f498ad043cf8da39a696d07095c69d662f56f694b30017f1675c
6
+ metadata.gz: ec33031cbabe0367c55e532adff3557527c309a700404bd0e19570e76ad4e199ae257f49fe4668a0550f33906aa5cdbeab2a0475b90222de85df356dd36ed38e
7
+ data.tar.gz: cdaf43ba742dddfa274acc83610e2a7895cf471139da9868eb588c46c20c723a12c261567f8e2b1e212ebdd587a10017d8c3fc90e0ba2d3d65801de943315c6a
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ = 3.4.12
2
+ - Workaround for counter_cache bug on polymorphic associations on rails4
3
+ - Improve use of CRUD actions without list action
4
+
1
5
  = 3.4.11
2
6
  - Fix refresh-link on main form (not subform)
3
7
  - Workaround for counter_cache bug on rails4 (https://github.com/rails/rails/pull/14849)
@@ -932,8 +932,8 @@ var ActiveScaffold = {
932
932
  if (send_form == 'row') base = element.closest('.association-record, form');
933
933
  if (selector = element.data('update_send_form_selector'))
934
934
  params = base.find(selector).serialize();
935
- else if (send_form != as_form) params = base.find(':input').serialize();
936
- else base.serialize();
935
+ else if (base != as_form) params = base.find(':input').serialize();
936
+ else params = base.serialize();
937
937
  params += '&_method=&' + jQuery.param({"source_id": source_id});
938
938
  if (additional_params) params += '&' + additional_params;
939
939
  } else {
@@ -9,7 +9,7 @@ data_refresh ||= record.to_param
9
9
  <tr class="record <%= tr_class %>" id="<%= row_id %>" data-refresh="<%= data_refresh %>">
10
10
  <% columns.each do |column| %>
11
11
  <% authorized = record.authorized_for?(:crud_type => :read, :column => column.name) -%>
12
- <% column_value = authorized ? get_column_value(record, column) : active_scaffold_config.list.empty_field_text -%>
12
+ <% column_value = authorized ? get_column_value(record, column) : empty_field_text -%>
13
13
 
14
14
  <%= content_tag :td, column_attributes(column, record).merge(:class => column_class(column, column_value, record)) do %>
15
15
  <%= authorized ? render_list_column(column_value, column, record) : column_value %>
@@ -1,5 +1,5 @@
1
1
  <% calculations_id ||= active_scaffold_calculations_id -%>
2
- <% if active_scaffold_config.list.columns.any? {|c| c.calculation?} %>
2
+ <% if active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.columns.any? {|c| c.calculation?} %>
3
3
  <% params.delete(:id) %>
4
4
  ActiveScaffold.replace('<%= calculations_id %>', '<%= escape_javascript(render(:partial => 'list_calculations')) %>');
5
5
  <% end %>
@@ -19,7 +19,7 @@
19
19
  <% else %>
20
20
  <%
21
21
  url = main_path_to_return
22
- url[:page] = [active_scaffold_config.list.user.page.to_i - 1, 1].max if url.is_a? Hash
22
+ url[:page] = [active_scaffold_config.list.user.page.to_i - 1, 1].max if url.is_a?(Hash) && active_scaffold_config.actions.include?(:list)
23
23
  %>
24
24
  ActiveScaffold.delete_record_row('<%= element_row_id(:action => 'list', :id => params[:id]) %>', '<%= url_for(url) %>');
25
25
  <%= render :partial => 'update_calculations', :formats => [:js] %>
@@ -1,8 +1,11 @@
1
1
  try {
2
2
  var action_link;
3
- <% form_selector ||= "#{element_form_id(:action => :create)}"
4
- insert_at ||= :top -%>
5
- <% if active_scaffold_config.list.always_show_create -%>
3
+ <%
4
+ form_selector ||= "#{element_form_id(:action => :create)}"
5
+ insert_at ||= :top
6
+ always_show_create ||= active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.always_show_create
7
+ -%>
8
+ <% if always_show_create -%>
6
9
  <%= render :partial => 'update_messages' %>
7
10
  <% else -%>
8
11
  action_link = ActiveScaffold.find_action_link('<%= form_selector %>');
@@ -26,7 +29,7 @@ action_link.update_flash_messages('<%= escape_javascript(render(:partial => 'mes
26
29
  <% end %>
27
30
 
28
31
  <% unless render_parent? %>
29
- <% if active_scaffold_config.list.always_show_create %>
32
+ <% if always_show_create %>
30
33
  ActiveScaffold.reset_form('<%= form_selector %>');
31
34
  <% elsif params[:dont_close] %>
32
35
  ActiveScaffold.replace('<%= form_selector %>','<%= escape_javascript(render(:partial => 'create_form', :locals => {:xhr => true})) %>');
@@ -71,7 +71,7 @@ module ActiveScaffold::Actions
71
71
  @record = new_model
72
72
  copy_attributes(record, @record) if record
73
73
  apply_constraints_to_record(@record) unless @scope
74
- @record = update_record_from_params(@record, @main_columns, hash, true)
74
+ @record = update_record_from_params(@record, @main_columns, hash || {}, true)
75
75
  else
76
76
  @record = params[:id] ? find_if_allowed(params[:id], :read) : new_model
77
77
  if @record.new_record?
@@ -229,6 +229,66 @@ module ActiveScaffold::Actions
229
229
  model.respond_to?(:build) ? model.build(build_options || {}) : model.new
230
230
  end
231
231
 
232
+ def get_row(crud_type_or_security_options = :read)
233
+ klass = beginning_of_chain.preload(active_scaffold_preload)
234
+ @record = find_if_allowed(params[:id], crud_type_or_security_options, klass)
235
+ end
236
+
237
+ # call this method in your action_link action to simplify processing of actions
238
+ # eg for member action_link :fire
239
+ # process_action_link_action do |record|
240
+ # record.update_attributes(:fired => true)
241
+ # self.successful = true
242
+ # flash[:info] = 'Player fired'
243
+ # end
244
+ def process_action_link_action(render_action = :action_update, crud_type_or_security_options = nil)
245
+ if request.get?
246
+ # someone has disabled javascript, we have to show confirmation form first
247
+ @record = find_if_allowed(params[:id], :read) if params[:id]
248
+ respond_to_action(:action_confirmation)
249
+ else
250
+ @action_link = active_scaffold_config.action_links[action_name]
251
+ if params[:id]
252
+ crud_type_or_security_options ||= {:crud_type => (request.post? || request.put?) ? :update : :delete, :action => action_name}
253
+ get_row(crud_type_or_security_options)
254
+ unless @record.nil?
255
+ yield @record
256
+ else
257
+ self.successful = false
258
+ flash[:error] = as_(:no_authorization_for_action, :action => action_name)
259
+ end
260
+ else
261
+ yield
262
+ end
263
+ respond_to_action(render_action)
264
+ end
265
+ end
266
+
267
+ def action_confirmation_respond_to_html(confirm_action = action_name.to_sym)
268
+ link = active_scaffold_config.action_links[confirm_action]
269
+ render :action => 'action_confirmation', :locals => {:record => @record, :link => link}
270
+ end
271
+
272
+ def action_update_respond_to_html
273
+ redirect_to :action => 'index'
274
+ end
275
+
276
+ def action_update_respond_to_js
277
+ render(:action => 'on_action_update')
278
+ end
279
+
280
+ def action_update_respond_to_xml
281
+ render :xml => successful? ? "" : response_object.to_xml(:only => list_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(list_columns_names), :methods => virtual_columns(list_columns_names)), :content_type => Mime::XML, :status => response_status
282
+ end
283
+
284
+ def action_update_respond_to_json
285
+ render :text => successful? ? "" : response_object.to_json(:only => list_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(list_columns_names), :methods => virtual_columns(list_columns_names)), :content_type => Mime::JSON, :status => response_status
286
+ end
287
+
288
+ def action_update_respond_to_yaml
289
+ render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => list_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(list_columns_names), :methods => virtual_columns(list_columns_names))).to_yaml, :content_type => Mime::YAML, :status => response_status
290
+ end
291
+
232
292
  def objects_for_etag
233
293
  @last_modified ||= @record.updated_at
234
294
  [@record, ('xhr' if request.xhr?)]
@@ -78,8 +78,7 @@ module ActiveScaffold::Actions
78
78
 
79
79
  def get_row(crud_type_or_security_options = :read)
80
80
  set_includes_for_columns
81
- klass = beginning_of_chain.preload(active_scaffold_preload)
82
- @record = find_if_allowed(params[:id], crud_type_or_security_options, klass)
81
+ super
83
82
  end
84
83
 
85
84
  # The actual algorithm to prepare for the list view
@@ -141,62 +140,11 @@ module ActiveScaffold::Actions
141
140
  authorized_for?(:crud_type => :read)
142
141
  end
143
142
 
144
- # call this method in your action_link action to simplify processing of actions
145
- # eg for member action_link :fire
146
- # process_action_link_action do |record|
147
- # record.update_attributes(:fired => true)
148
- # self.successful = true
149
- # flash[:info] = 'Player fired'
150
- # end
151
- def process_action_link_action(render_action = :action_update, crud_type_or_security_options = nil)
152
- if request.get?
153
- # someone has disabled javascript, we have to show confirmation form first
154
- @record = find_if_allowed(params[:id], :read) if params[:id]
155
- respond_to_action(:action_confirmation)
156
- else
157
- @action_link = active_scaffold_config.action_links[action_name]
158
- if params[:id]
159
- crud_type_or_security_options ||= {:crud_type => (request.post? || request.put?) ? :update : :delete, :action => action_name}
160
- get_row(crud_type_or_security_options)
161
- unless @record.nil?
162
- yield @record
163
- else
164
- self.successful = false
165
- flash[:error] = as_(:no_authorization_for_action, :action => action_name)
166
- end
167
- else
168
- yield
169
- end
170
- respond_to_action(render_action)
171
- end
172
- end
173
-
174
- def action_confirmation_respond_to_html(confirm_action = action_name.to_sym)
175
- link = active_scaffold_config.action_links[confirm_action]
176
- render :action => 'action_confirmation', :locals => {:record => @record, :link => link}
177
- end
178
-
179
- def action_update_respond_to_html
180
- redirect_to :action => 'index'
181
- end
182
-
183
143
  def action_update_respond_to_js
184
144
  do_refresh_list unless @record.present?
185
- render(:action => 'on_action_update')
186
- end
187
-
188
- def action_update_respond_to_xml
189
- render :xml => successful? ? "" : response_object.to_xml(:only => list_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(list_columns_names), :methods => virtual_columns(list_columns_names)), :content_type => Mime::XML, :status => response_status
190
- end
191
-
192
- def action_update_respond_to_json
193
- render :text => successful? ? "" : response_object.to_json(:only => list_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(list_columns_names), :methods => virtual_columns(list_columns_names)), :content_type => Mime::JSON, :status => response_status
194
- end
195
-
196
- def action_update_respond_to_yaml
197
- render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => list_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(list_columns_names), :methods => virtual_columns(list_columns_names))).to_yaml, :content_type => Mime::YAML, :status => response_status
145
+ super
198
146
  end
199
-
147
+
200
148
  def objects_for_etag
201
149
  objects = if @list_columns
202
150
  if active_scaffold_config.list.calculate_etag
@@ -32,6 +32,7 @@ module ActiveScaffold::Actions
32
32
  def edit_respond_to_js
33
33
  render(:partial => 'update_form')
34
34
  end
35
+
35
36
  def update_respond_to_html
36
37
  if params[:iframe]=='true' # was this an iframe post ?
37
38
  do_refresh_list if successful? && active_scaffold_config.update.refresh_list && !render_parent?
@@ -41,18 +42,19 @@ module ActiveScaffold::Actions
41
42
  else # just a regular post
42
43
  if successful?
43
44
  message = as_(:updated_model, :model => @record.to_label)
44
- if params[:dont_close]
45
- flash.now[:info] = message
46
- render(:action => 'update')
47
- else
48
- flash[:info] = message
49
- return_to_main
50
- end
45
+ if params[:dont_close]
46
+ flash.now[:info] = message
47
+ render(:action => 'update')
48
+ else
49
+ flash[:info] = message
50
+ return_to_main
51
+ end
51
52
  else
52
53
  render(:action => 'update')
53
54
  end
54
55
  end
55
56
  end
57
+
56
58
  def update_respond_to_js
57
59
  if successful?
58
60
  if !render_parent? && active_scaffold_config.actions.include?(:list)
@@ -68,12 +70,15 @@ module ActiveScaffold::Actions
68
70
  end
69
71
  render :action => 'on_update'
70
72
  end
73
+
71
74
  def update_respond_to_xml
72
75
  render :xml => response_object.to_xml(:only => update_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(update_columns_names), :methods => virtual_columns(update_columns_names)), :content_type => Mime::XML, :status => response_status
73
76
  end
77
+
74
78
  def update_respond_to_json
75
79
  render :text => response_object.to_json(:only => update_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(update_columns_names), :methods => virtual_columns(update_columns_names)), :content_type => Mime::JSON, :status => response_status
76
80
  end
81
+
77
82
  def update_respond_to_yaml
78
83
  render :text => Hash.from_xml(response_object.to_xml(:only => update_columns_names + [active_scaffold_config.model.primary_key], :include => association_columns(update_columns_names), :methods => virtual_columns(update_columns_names))).to_yaml, :content_type => Mime::YAML, :status => response_status
79
84
  end
@@ -33,25 +33,42 @@ module ActiveScaffold
33
33
  module AttributeParams
34
34
  protected
35
35
  # workaround to update counters when belongs_to changes on persisted record on Rails 3
36
- # TODO remove when rails3 support is removed
37
- def rails3_counter_cache_hack(parent_record, column, value)
36
+ # workaround to update counters when polymorphic has_many changes on persisted record
37
+ # TODO remove when rails3 support is removed and counter cache for polymorphic has_many association works on rails4 (works on rails4.2)
38
+ def has_many_counter_cache_hack(parent_record, column, value)
38
39
  association = parent_record.association(column.name)
39
- if association.send(:has_cached_counter?)
40
- counter_attr = association.send(:cached_counter_attribute_name)
41
- difference = value.select(&:persisted?).size - parent_record.send(counter_attr)
40
+ counter_attr = association.send(:cached_counter_attribute_name)
41
+ difference = value.select(&:persisted?).size - parent_record.send(counter_attr)
42
42
 
43
- if parent_record.new_record?
43
+ if parent_record.new_record?
44
+ if Rails.version < '4.2'
44
45
  parent_record.send "#{counter_attr}=", difference
46
+ parent_record.send "#{column.name}=", value
45
47
  else
46
- # don't decrement counter for deleted records, on destroy they will update counter
47
- difference += (parent_record.send(column.name) - value).size
48
- association.send :update_counter, difference unless difference == 0
48
+ parent_record.send "#{column.name}=", value
49
+ parent_record.send "#{counter_attr}_will_change!"
49
50
  end
51
+ else
52
+ # don't decrement counter for deleted records, on destroy they will update counter
53
+ difference += (parent_record.send(column.name) - value).size
54
+ association.send :update_counter, difference unless difference == 0
55
+ end
50
56
 
51
- # update counters on old parents if belongs_to is changed
52
- value.select(&:persisted?).each do |record|
53
- key = record.send(column.association.foreign_key)
54
- parent_record.class.decrement_counter counter_attr, key if key != parent_record.id
57
+ # update counters on old parents if belongs_to is changed
58
+ value.select(&:persisted?).each do |record|
59
+ key = record.send(column.association.foreign_key)
60
+ parent_record.class.decrement_counter counter_attr, key if key && key != parent_record.id
61
+ end
62
+ parent_record.send "#{column.name}=", value if parent_record.persisted?
63
+ end
64
+
65
+ # TODO remove when has_many_counter_cache_hack is not needed
66
+ def has_many_counter_cache_hack?(parent_record, column)
67
+ if column.association.try(:macro) == :has_many && parent_record.association(column.name).send(:has_cached_counter?)
68
+ if Rails.version < '4.0' # rails 3 needs this hack always
69
+ true
70
+ else # rails 4 needs this hack for polymorphic has_many
71
+ column.association.options[:as]
55
72
  end
56
73
  end
57
74
  end
@@ -59,7 +76,9 @@ module ActiveScaffold
59
76
  # workaround for updating counters twice bug on rails4 (https://github.com/rails/rails/pull/14849)
60
77
  # TODO remove when pull request is merged and no version with bug is supported
61
78
  def counter_cache_hack?(column, value)
62
- Rails.version >= '4.0' && column.association.try(:belongs_to?) && column.association.options[:counter_cache] && !value.is_a?(Hash)
79
+ if Rails.version >= '4.0' && !value.is_a?(Hash)
80
+ column.association.try(:belongs_to?) && column.association.options[:counter_cache] && !column.association.options[:polymorphic]
81
+ end
63
82
  end
64
83
 
65
84
  # Takes attributes (as from params[:record]) and applies them to the parent_record. Also looks for
@@ -89,24 +108,7 @@ module ActiveScaffold
89
108
  if multi_parameter_attributes.has_key? column.name.to_s
90
109
  parent_record.send(:assign_multiparameter_attributes, multi_parameter_attributes[column.name.to_s])
91
110
  elsif attributes.has_key? column.name
92
- value = column_value_from_param_value(parent_record, column, attributes[column.name], avoid_changes)
93
- if avoid_changes && column.plural_association?
94
- parent_record.association(column.name).target = value
95
- elsif counter_cache_hack?(column, attributes[column.name])
96
- parent_record.send "#{column.association.foreign_key}=", value.try(:id)
97
- parent_record.association(column.name).target = value
98
- else
99
- begin
100
- rails3_counter_cache_hack(parent_record, column, value) if Rails.version < '4.0' && column.plural_association?
101
- parent_record.send "#{column.name}=", value
102
- rescue ActiveRecord::RecordNotSaved
103
- parent_record.errors.add column.name, :invalid
104
- parent_record.association(column.name).target = value if column.association
105
- end
106
- end
107
- if column.association && [:has_one, :has_many].include?(column.association.macro) && column.association.reverse
108
- Array(value).each { |v| v.send("#{column.association.reverse}=", parent_record) if v.new_record? }
109
- end
111
+ value = update_column_from_params(parent_record, column, attributes[column.name], avoid_changes)
110
112
  end
111
113
  rescue
112
114
  logger.error "#{$!.class.name}: #{$!.message} -- on the ActiveScaffold column = :#{column.name} for #{parent_record.inspect}#{" with value #{value}" if value}"
@@ -117,6 +119,31 @@ module ActiveScaffold
117
119
  flash[:warning] = parent_record.errors.to_a.join("\n") if parent_record.errors.present?
118
120
  parent_record
119
121
  end
122
+
123
+ def update_column_from_params(parent_record, column, attribute, avoid_changes = false)
124
+ value = column_value_from_param_value(parent_record, column, attribute, avoid_changes)
125
+ if avoid_changes && column.plural_association?
126
+ parent_record.association(column.name).target = value
127
+ elsif counter_cache_hack?(column, attribute)
128
+ parent_record.send "#{column.association.foreign_key}=", value.try(:id)
129
+ parent_record.association(column.name).target = value
130
+ else
131
+ begin
132
+ if has_many_counter_cache_hack?(parent_record, column)
133
+ has_many_counter_cache_hack(parent_record, column, value)
134
+ else
135
+ parent_record.send "#{column.name}=", value
136
+ end
137
+ rescue ActiveRecord::RecordNotSaved
138
+ parent_record.errors.add column.name, :invalid
139
+ parent_record.association(column.name).target = value if column.association
140
+ end
141
+ end
142
+ if column.association && [:has_one, :has_many].include?(column.association.macro) && column.association.reverse
143
+ Array(value).each { |v| v.send("#{column.association.reverse}=", parent_record) if v.new_record? }
144
+ end
145
+ value
146
+ end
120
147
 
121
148
  def column_value_from_param_value(parent_record, column, value, avoid_changes = false)
122
149
  # convert the value, possibly by instantiating associated objects
@@ -48,7 +48,7 @@ module ActiveScaffold
48
48
  render_action_link(link, record, :link => text, :authorized => link.action.nil? || column_link_authorized?(link, column, record, associated))
49
49
  elsif inplace_edit?(record, column)
50
50
  active_scaffold_inplace_edit(record, column, {:formatted_column => text})
51
- elsif active_scaffold_config.list.wrap_tag
51
+ elsif active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.wrap_tag
52
52
  content_tag active_scaffold_config.list.wrap_tag, text
53
53
  else
54
54
  text
@@ -176,7 +176,7 @@ module ActiveScaffold
176
176
 
177
177
  def format_value(column_value, options = {})
178
178
  value = if column_empty?(column_value)
179
- active_scaffold_config.list.empty_field_text
179
+ empty_field_text
180
180
  elsif column_value.is_a?(Time) || column_value.is_a?(Date)
181
181
  l(column_value, :format => options[:format] || :default)
182
182
  elsif [FalseClass, TrueClass].include?(column_value.class)
@@ -492,7 +492,7 @@ module ActiveScaffold
492
492
  @_column_classes ||= {}
493
493
  @_column_classes[column.name] ||= begin
494
494
  classes = "#{column.name}-column "
495
- classes << 'sorted ' if active_scaffold_config.list.user.sorting.sorts_on?(column)
495
+ classes << 'sorted ' if active_scaffold_config.actions.include?(:list) && active_scaffold_config.list.user.sorting.sorts_on?(column)
496
496
  classes << 'numeric ' if column.number?
497
497
  classes << column.css_class unless column.css_class.nil? || column.css_class.is_a?(Proc)
498
498
  end
@@ -522,9 +522,13 @@ module ActiveScaffold
522
522
  def column_empty?(column_value)
523
523
  empty = column_value.nil?
524
524
  empty ||= false != column_value && column_value.blank?
525
- empty ||= ['&nbsp;', active_scaffold_config.list.empty_field_text].include? column_value if String === column_value
525
+ empty ||= ['&nbsp;', empty_field_text].include? column_value if String === column_value
526
526
  return empty
527
527
  end
528
+
529
+ def empty_field_text
530
+ active_scaffold_config.list.empty_field_text if active_scaffold_config.actions.include?(:list)
531
+ end
528
532
 
529
533
  def column_calculation(column)
530
534
  unless column.calculate.instance_of? Proc
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 4
5
- PATCH = 11
5
+ PATCH = 12
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
@@ -10,7 +10,7 @@ class ListColumnHelpersTest < ActionView::TestCase
10
10
  @column = ActiveScaffold::DataStructures::Column.new(:a, ModelStub)
11
11
  @column.form_ui = :select
12
12
  @record = stub(:a => 'value_2')
13
- @config = stub(:list => stub(:empty_field_text => '-', :association_join_text => ', '))
13
+ @config = stub(:list => stub(:empty_field_text => '-', :association_join_text => ', '), :actions => [:list])
14
14
  @association_column = ActiveScaffold::DataStructures::Column.new(:b, ModelStub)
15
15
  @association_column.stubs(:association).returns(stub(:collection? => true))
16
16
  end
@@ -45,7 +45,7 @@ class AttributeParamsTest < MiniTest::Test
45
45
  assert_equal 'First', model.first_name
46
46
  assert_nil model.last_name
47
47
  assert_equal buildings.map(&:id), model.building_ids
48
- assert_equal buildings, model.buildings
48
+ assert_equal buildings.map(&:id), model.buildings.map(&:id)
49
49
  assert model.save
50
50
  assert_equal 2, model.reload.buildings_count
51
51
 
@@ -332,26 +332,76 @@ class AttributeParamsTest < MiniTest::Test
332
332
  assert_equal person.id, model.contactable_id
333
333
  assert_equal person, model.contactable
334
334
  assert model.save
335
+ assert_equal 1, person.reload.contacts_count
335
336
 
336
337
  model = update_record_from_params(model, :update, :first_name, :contactable_type, :contactable, :first_name => 'Name', :contactable_type => person.class.name, :contactable => '')
337
338
  assert_equal 'Name', model.first_name
338
- assert_nil model.contactable_type
339
339
  assert_nil model.contactable_id, 'contactable should be cleared'
340
340
  assert_nil model.contactable, 'contactable should be cleared'
341
341
  assert_equal person.id, Contact.find(model.id).contactable_id, 'contact should not be saved yet'
342
342
  assert model.save
343
343
  assert_nil Contact.find(model.id).contactable_id, 'contact should be saved'
344
+ assert_equal 0, person.reload.contacts_count
345
+ end
346
+
347
+ def test_saving_has_many_polymorphic_select
348
+ contacts = 2.times.map { Contact.create }
349
+
350
+ model = update_record_from_params(Person.new, :create, :first_name, :contacts, :first_name => 'Me', :contacts => ['', contacts.first.id.to_s])
351
+ assert_equal 'Me', model.first_name
352
+ assert model.contacts.present?
353
+ assert model.save
354
+ assert_equal [model.id], model.contacts.map(&:contactable_id)
355
+ assert_equal model.id, contacts.first.reload.contactable.id, 'contactable should be saved'
356
+ assert_equal 1, model.reload.contacts_count
357
+
358
+ model = update_record_from_params(model, :update, :first_name, :contacts, :first_name => 'Name', :contacts => ['', *contacts.map{|c| c.id.to_s}])
359
+ assert_equal 'Name', model.first_name
360
+ assert model.contacts.present?
361
+ assert model.save
362
+ assert_equal [model.id]*2, model.contacts.map(&:contactable_id)
363
+ assert_equal [model.id]*2, contacts.map {|c| c.reload.contactable.id}, 'contactable should be saved'
364
+ assert_equal 2, model.reload.contacts_count
365
+
366
+ model = update_record_from_params(model, :update, :first_name, :contacts, :first_name => 'Name', :contacts => [''])
367
+ assert_equal 'Name', model.first_name
368
+ assert model.contacts.empty?
369
+ assert model.save
370
+ assert_equal [nil]*2, contacts.map {|c| c.reload.contactable}, 'contactable should be saved'
371
+ assert_equal 0, model.reload.contacts_count
372
+ end
373
+
374
+ def test_saving_habtm_select
375
+ roles = 2.times.map { Role.create }
376
+
377
+ model = update_record_from_params(Person.new, :create, :first_name, :roles, :first_name => 'Me', :roles => ['', roles.first.id.to_s])
378
+ assert_equal 'Me', model.first_name
379
+ assert model.roles.present?
380
+ assert model.save
381
+ assert_equal [[model.id]], model.roles.map(&:person_ids)
382
+ assert_equal [model.id], roles.first.reload.person_ids, 'role should be saved'
383
+
384
+ model = update_record_from_params(model, :update, :first_name, :roles, :first_name => 'Name', :roles => ['', *roles.map{|c| c.id.to_s}])
385
+ assert_equal 'Name', model.first_name
386
+ assert model.roles.present?
387
+ assert model.save
388
+ assert_equal [[model.id]]*2, model.roles.map(&:person_ids)
389
+ assert_equal [[model.id]]*2, roles.map {|r| r.reload.person_ids}, 'roles should be saved'
390
+
391
+ model = update_record_from_params(model, :update, :first_name, :roles, :first_name => 'Name', :roles => [''])
392
+ assert_equal 'Name', model.first_name
393
+ assert model.roles.empty?
394
+ assert model.save
395
+ assert roles.all? {|r| r.reload.people.empty?}, 'roles should be saved'
344
396
  end
345
397
 
346
398
  protected
347
- MODELS = [Address, Building, Car, Contact, Floor, Person]
348
399
  def update_record_from_params(record, action, *columns, &block)
349
400
  params = columns.extract_options!.with_indifferent_access
350
401
  new_record = nil
351
402
  record.class.transaction do
352
403
  record = record.class.find(record.id) if record.persisted?
353
404
  new_record = @controller.update_record_from_params(record, build_action_columns(record, action, columns), params)
354
- MODELS.each { |model| model.any_instance.unstub(:save) }
355
405
  yield if block_given?
356
406
  Thread.current[:constraint_columns] = nil
357
407
  end
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class TablelessTest < MiniTest::Test
4
4
  def test_find_all
5
- assert_equal [], FileModel.all
5
+ assert FileModel.all.to_a.empty?
6
6
  end
7
7
 
8
8
  def test_find_by_id
@@ -12,7 +12,7 @@ class TablelessTest < MiniTest::Test
12
12
  end
13
13
 
14
14
  def test_find_with_association
15
- assert_equal [], Person.new.files
15
+ assert Person.new.files.empty?
16
16
  end
17
17
  end
18
18
 
@@ -1,3 +1,3 @@
1
1
  class Contact < ActiveRecord::Base
2
- belongs_to :contactable, :polymorphic => true
2
+ belongs_to :contactable, :polymorphic => true, :counter_cache => true
3
3
  end
@@ -6,6 +6,7 @@ class Person < ActiveRecord::Base
6
6
 
7
7
  has_many :contacts, :as => :contactable
8
8
  has_one :car, :dependent => :destroy
9
+ has_and_belongs_to_many :roles
9
10
 
10
11
  has_many :files, :dependent => :destroy, :class_name => 'FileModel'
11
12
  end
@@ -0,0 +1,3 @@
1
+ class Role < ActiveRecord::Base
2
+ has_and_belongs_to_many :people
3
+ end
@@ -47,8 +47,20 @@ ActiveRecord::Schema.define do
47
47
  t.string 'last_name'
48
48
  t.integer 'buildings_count', :null => false, :default => 0
49
49
  t.integer 'floors_count', :null => false, :default => 0
50
+ t.integer 'contacts_count', :null => false, :default => 0
50
51
  t.datetime "created_at"
51
52
  t.datetime "updated_at"
52
53
  end
53
54
 
55
+ create_table 'roles' do |t|
56
+ t.string 'name'
57
+ t.datetime "created_at"
58
+ t.datetime "updated_at"
59
+ end
60
+
61
+ create_table 'people_roles', :id => false do |t|
62
+ t.integer 'person_id'
63
+ t.integer 'role_id'
64
+ end
65
+
54
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.11
4
+ version: 3.4.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Many, see README
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-10 00:00:00.000000000 Z
11
+ date: 2014-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: shoulda
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rcov
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rails
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -82,6 +68,9 @@ extensions: []
82
68
  extra_rdoc_files:
83
69
  - README.md
84
70
  files:
71
+ - CHANGELOG
72
+ - MIT-LICENSE
73
+ - README.md
85
74
  - app/assets/images/active_scaffold/add.png
86
75
  - app/assets/images/active_scaffold/arrow_down.png
87
76
  - app/assets/images/active_scaffold/arrow_up.png
@@ -312,27 +301,6 @@ files:
312
301
  - lib/generators/active_scaffold_controller/templates/helper.rb
313
302
  - public/blank.html
314
303
  - shoulda_macros/macros.rb
315
- - vendor/assets/images/ui-bg_diagonals-thick_18_b81900_40x40.png
316
- - vendor/assets/images/ui-bg_diagonals-thick_20_666666_40x40.png
317
- - vendor/assets/images/ui-bg_flat_10_000000_40x100.png
318
- - vendor/assets/images/ui-bg_glass_100_f6f6f6_1x400.png
319
- - vendor/assets/images/ui-bg_glass_100_fdf5ce_1x400.png
320
- - vendor/assets/images/ui-bg_glass_65_ffffff_1x400.png
321
- - vendor/assets/images/ui-bg_gloss-wave_35_f6a828_500x100.png
322
- - vendor/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
323
- - vendor/assets/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
324
- - vendor/assets/images/ui-icons_222222_256x240.png
325
- - vendor/assets/images/ui-icons_228ef1_256x240.png
326
- - vendor/assets/images/ui-icons_ef8c08_256x240.png
327
- - vendor/assets/images/ui-icons_ffd27a_256x240.png
328
- - vendor/assets/images/ui-icons_ffffff_256x240.png
329
- - vendor/assets/javascripts/getprototypeof.js
330
- - vendor/assets/javascripts/jquery-ui-timepicker-addon.js
331
- - vendor/assets/stylesheets/jquery-ui-theme.css.erb
332
- - vendor/assets/stylesheets/jquery-ui.css
333
- - MIT-LICENSE
334
- - CHANGELOG
335
- - README.md
336
304
  - test/bridges/bridge_test.rb
337
305
  - test/bridges/date_picker_test.rb
338
306
  - test/bridges/paperclip_test.rb
@@ -394,6 +362,7 @@ files:
394
362
  - test/mock_app/app/models/file_model.rb
395
363
  - test/mock_app/app/models/floor.rb
396
364
  - test/mock_app/app/models/person.rb
365
+ - test/mock_app/app/models/role.rb
397
366
  - test/mock_app/config.ru
398
367
  - test/mock_app/config/application.rb
399
368
  - test/mock_app/config/boot.rb
@@ -415,6 +384,24 @@ files:
415
384
  - test/model_stub.rb
416
385
  - test/run_all.rb
417
386
  - test/test_helper.rb
387
+ - vendor/assets/images/ui-bg_diagonals-thick_18_b81900_40x40.png
388
+ - vendor/assets/images/ui-bg_diagonals-thick_20_666666_40x40.png
389
+ - vendor/assets/images/ui-bg_flat_10_000000_40x100.png
390
+ - vendor/assets/images/ui-bg_glass_100_f6f6f6_1x400.png
391
+ - vendor/assets/images/ui-bg_glass_100_fdf5ce_1x400.png
392
+ - vendor/assets/images/ui-bg_glass_65_ffffff_1x400.png
393
+ - vendor/assets/images/ui-bg_gloss-wave_35_f6a828_500x100.png
394
+ - vendor/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
395
+ - vendor/assets/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
396
+ - vendor/assets/images/ui-icons_222222_256x240.png
397
+ - vendor/assets/images/ui-icons_228ef1_256x240.png
398
+ - vendor/assets/images/ui-icons_ef8c08_256x240.png
399
+ - vendor/assets/images/ui-icons_ffd27a_256x240.png
400
+ - vendor/assets/images/ui-icons_ffffff_256x240.png
401
+ - vendor/assets/javascripts/getprototypeof.js
402
+ - vendor/assets/javascripts/jquery-ui-timepicker-addon.js
403
+ - vendor/assets/stylesheets/jquery-ui-theme.css.erb
404
+ - vendor/assets/stylesheets/jquery-ui.css
418
405
  homepage: http://activescaffold.com
419
406
  licenses:
420
407
  - MIT
@@ -435,7 +422,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
435
422
  version: '0'
436
423
  requirements: []
437
424
  rubyforge_project:
438
- rubygems_version: 2.1.11
425
+ rubygems_version: 2.4.5
439
426
  signing_key:
440
427
  specification_version: 4
441
428
  summary: Rails 3.2 and 4.0 version of activescaffold supporting prototype and jquery
@@ -501,6 +488,7 @@ test_files:
501
488
  - test/mock_app/app/models/file_model.rb
502
489
  - test/mock_app/app/models/floor.rb
503
490
  - test/mock_app/app/models/person.rb
491
+ - test/mock_app/app/models/role.rb
504
492
  - test/mock_app/config.ru
505
493
  - test/mock_app/config/application.rb
506
494
  - test/mock_app/config/boot.rb