active_scaffold 3.4.11 → 3.4.12

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