active_scaffold 3.2.8 → 3.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,4 +1,8 @@
1
- = 3.2.8 (not released)
1
+ = 3.2.9 (not released)
2
+ - remove duplicated conditions with constraints
3
+ - fix constraints for polymorphic associations
4
+
5
+ = 3.2.8
2
6
  - add deprecation for update_column, update_columns should be used instead
3
7
  - fix constraints with hide_nested_column disabled in list and embedded scaffolds which are nested too
4
8
  - fix setting a hash as includes, cannot be concat in finder
@@ -27,7 +27,6 @@ module ActiveScaffold::Actions
27
27
  end
28
28
 
29
29
  def render_field_for_inplace_editing
30
- register_constraints_with_action_columns(active_scaffold_config.update.hide_nested_column ? [] : [:update]) if nested?
31
30
  @record = find_if_allowed(params[:id], :update)
32
31
  render :inline => "<%= active_scaffold_input_for(active_scaffold_config.columns[params[:update_column].to_sym]) %>"
33
32
  end
@@ -151,25 +150,22 @@ module ActiveScaffold::Actions
151
150
 
152
151
  # Builds search conditions by search params for column names. This allows urls like "contacts/list?company_id=5".
153
152
  def conditions_from_params
154
- conditions = nil
153
+ conditions = {}
155
154
  params.reject {|key, value| [:controller, :action, :id, :page, :sort, :sort_direction].include?(key.to_sym)}.each do |key, value|
156
- next unless active_scaffold_config.model.column_names.include?(key)
157
- if value.is_a?(Array)
158
- conditions = merge_conditions(conditions, ["#{active_scaffold_config.model.table_name}.#{key.to_s} in (?)", value])
159
- else
160
- conditions = merge_conditions(conditions, ["#{active_scaffold_config.model.table_name}.#{key.to_s} = ?", value])
161
- end
155
+ next unless active_scaffold_config.model.columns_hash[key.to_s]
156
+ next if active_scaffold_constraints[key.to_sym]
157
+ conditions[key] = value
162
158
  end
163
159
  conditions
164
160
  end
165
161
 
166
162
  def new_model
167
163
  model = beginning_of_chain
168
- if model.columns_hash[model.inheritance_column]
169
- build_options = {model.inheritance_column.to_sym => active_scaffold_config.model_id} if nested? && nested.association && nested.association.collection?
170
- params = self.params # in new action inheritance_column must be in params
171
- params = params[:record] || {} unless params[model.inheritance_column] # in create action must be inside record key
172
- model = params.delete(model.inheritance_column).camelize.constantize if params[model.inheritance_column]
164
+ if model.columns_hash[column = model.inheritance_column]
165
+ build_options = {column.to_sym => active_scaffold_config.model_id} if nested? && nested.association && nested.association.collection?
166
+ model_name = params.delete(column) # in new action inheritance_column must be in params
167
+ model_name ||= params[:record].delete(column) unless params[:record].blank? # in create action must be inside record key
168
+ model = model_name.camelize.constantize if model_name
173
169
  end
174
170
  model.respond_to?(:build) ? model.build(build_options || {}) : model.new
175
171
  end
@@ -78,10 +78,7 @@ module ActiveScaffold::Actions
78
78
  def do_new
79
79
  @record = new_model
80
80
  apply_constraints_to_record(@record)
81
- if nested?
82
- create_association_with_parent(@record)
83
- register_constraints_with_action_columns
84
- end
81
+ create_association_with_parent(@record) if nested?
85
82
  @record
86
83
  end
87
84
 
@@ -93,10 +90,7 @@ module ActiveScaffold::Actions
93
90
  active_scaffold_config.model.transaction do
94
91
  @record = update_record_from_params(new_model, active_scaffold_config.create.columns, hash)
95
92
  apply_constraints_to_record(@record, :allow_autosave => true)
96
- if nested?
97
- create_association_with_parent(@record)
98
- register_constraints_with_action_columns
99
- end
93
+ create_association_with_parent(@record) if nested?
100
94
  create_save
101
95
  end
102
96
  rescue ActiveRecord::ActiveRecordError => ex
@@ -43,23 +43,19 @@ module ActiveScaffold::Actions
43
43
 
44
44
  def do_search
45
45
  unless search_params.blank?
46
+ filtered_columns = []
46
47
  text_search = active_scaffold_config.field_search.text_search
47
- search_conditions = []
48
- human_condition_columns = [] if active_scaffold_config.field_search.human_conditions
49
48
  columns = active_scaffold_config.field_search.columns
50
49
  search_params.each do |key, value|
51
50
  next unless columns.include? key
52
51
  search_condition = self.class.condition_for_column(active_scaffold_config.columns[key], value, text_search)
53
52
  unless search_condition.blank?
54
- search_conditions << search_condition
55
- human_condition_columns << active_scaffold_config.columns[key] unless human_condition_columns.nil?
53
+ self.active_scaffold_conditions << search_condition
54
+ filtered_columns << active_scaffold_config.columns[key]
56
55
  end
57
56
  end
58
- self.active_scaffold_conditions = merge_conditions(self.active_scaffold_conditions, *search_conditions)
59
- if search_conditions.blank?
60
- @filtered = false
61
- else
62
- @filtered = human_condition_columns.nil? ? true : human_condition_columns
57
+ unless filtered_columns.blank?
58
+ @filtered = active_scaffold_config.field_search.human_conditions ? filtered_columns : true
63
59
  end
64
60
 
65
61
  includes_for_search_columns = columns.collect{ |column| column.includes}.flatten.uniq.compact
@@ -26,11 +26,7 @@ module ActiveScaffold::Actions
26
26
  def set_nested
27
27
  if params[:parent_scaffold] && (params[:association] || params[:named_scope])
28
28
  @nested = ActiveScaffold::DataStructures::NestedInfo.get(active_scaffold_config.model, params)
29
- unless @nested.nil?
30
- active_scaffold_constraints.merge! @nested.constraints
31
- active_scaffold_constraints[:id] = params[:id] if @nested.belongs_to?
32
- register_constraints_with_action_columns
33
- end
29
+ register_constraints_with_action_columns(@nested.constrained_fields) unless @nested.nil?
34
30
  end
35
31
  end
36
32
 
@@ -86,7 +82,7 @@ module ActiveScaffold::Actions
86
82
  elsif nested? && nested.scope
87
83
  nested.parent_scope.send(nested.scope)
88
84
  else
89
- active_scaffold_config.model
85
+ super
90
86
  end
91
87
  end
92
88
 
@@ -26,8 +26,8 @@ module ActiveScaffold::Actions
26
26
  text_search = active_scaffold_config.search.text_search
27
27
  query = query.split(active_scaffold_config.search.split_terms) if active_scaffold_config.search.split_terms
28
28
  search_conditions = self.class.create_conditions_for_columns(query, columns, text_search)
29
- self.active_scaffold_conditions = merge_conditions(self.active_scaffold_conditions, search_conditions)
30
29
  @filtered = !search_conditions.blank?
30
+ self.active_scaffold_conditions.concat search_conditions if @filtered
31
31
 
32
32
  includes_for_search_columns = columns.collect{ |column| column.includes}.flatten.uniq.compact
33
33
  self.active_scaffold_includes.concat includes_for_search_columns
@@ -65,7 +65,6 @@ module ActiveScaffold::Actions
65
65
  # A simple method to find and prepare a record for editing
66
66
  # May be overridden to customize the record (set default values, etc.)
67
67
  def do_edit
68
- register_constraints_with_action_columns(active_scaffold_config.update.hide_nested_column ? [] : [:update]) if nested?
69
68
  @record = find_if_allowed(params[:id], :update)
70
69
  end
71
70
 
@@ -41,6 +41,7 @@ module ActiveRecordPermissions
41
41
  module Model
42
42
  def self.included(base)
43
43
  base.extend ClassMethods
44
+ base.send :include, ActiveRecordPermissions::Permissions
44
45
  end
45
46
 
46
47
  module ClassMethods
@@ -5,6 +5,7 @@ module ActiveScaffold::Config
5
5
 
6
6
  def initialize(core_config)
7
7
  @core = core_config
8
+ @action_group = self.class.action_group.clone if self.class.action_group
8
9
  end
9
10
 
10
11
  def self.inherited(subclass)
@@ -62,9 +63,12 @@ module ActiveScaffold::Config
62
63
  private
63
64
 
64
65
  def columns=(val)
65
- @columns = ActiveScaffold::DataStructures::ActionColumns.new(*val)
66
- @columns.action = self
67
- @columns.set_columns(@core.columns) if @columns.respond_to?(:set_columns)
66
+ @columns.set_values(*val) if @column
67
+ @columns ||= ActiveScaffold::DataStructures::ActionColumns.new(*val).tap do |columns|
68
+ columns.action = self
69
+ columns.set_columns(@core.columns) if @columns.respond_to?(:set_columns)
70
+ columns
71
+ end
68
72
  @columns
69
73
  end
70
74
  end
@@ -4,9 +4,7 @@ module ActiveScaffold::Config
4
4
  def initialize(core_config)
5
5
  super
6
6
  @label = :create_model
7
- self.persistent = self.class.persistent
8
7
  self.action_after_create = self.class.action_after_create
9
- self.refresh_list = self.class.refresh_list
10
8
  end
11
9
 
12
10
  # global level configuration
@@ -20,25 +18,15 @@ module ActiveScaffold::Config
20
18
  end
21
19
  @@link = ActiveScaffold::DataStructures::ActionLink.new('new', :label => :create_new, :type => :collection, :security_method => :create_authorized?, :ignore_method => :create_ignore?)
22
20
 
23
- # whether the form stays open after a create or not
24
- cattr_accessor :persistent
25
- @@persistent = false
26
-
27
21
  # whether update form is opened after a create or not
28
22
  cattr_accessor :action_after_create
29
23
  @@action_after_create = nil
30
24
 
31
- # whether we should refresh list after create or not
32
- cattr_accessor :refresh_list
33
- @@refresh_list = false
34
-
35
- # whether the form stays open after a create or not
36
- attr_accessor :persistent
25
+ # instance-level configuration
26
+ # ----------------------------
37
27
 
38
28
  # whether the form stays open after a create or not
39
29
  attr_accessor :action_after_create
40
30
 
41
- # whether we should refresh list after create or not
42
- attr_accessor :refresh_list
43
31
  end
44
32
  end
@@ -6,8 +6,7 @@ module ActiveScaffold::Config
6
6
  super
7
7
  # start with the ActionLink defined globally
8
8
  @link = self.class.link.clone
9
- @action_group = self.class.action_group.clone if self.class.action_group
10
- self.refresh_list = self.class.refresh_list
9
+ @refresh_list = self.class.refresh_list
11
10
  end
12
11
 
13
12
  # global level configuration
@@ -5,10 +5,10 @@ module ActiveScaffold::Config
5
5
  def initialize(core_config)
6
6
  super
7
7
  @text_search = self.class.text_search
8
+ @human_conditions = self.class.human_conditions
8
9
 
9
10
  # start with the ActionLink defined globally
10
11
  @link = self.class.link.clone
11
- @action_group = self.class.action_group.clone if self.class.action_group
12
12
  end
13
13
 
14
14
 
@@ -27,6 +27,11 @@ module ActiveScaffold::Config
27
27
  cattr_accessor :text_search
28
28
  @@text_search = :full
29
29
 
30
+ # human conditions
31
+ # instead of just filtered you may show the user a humanized search condition statment
32
+ cattr_accessor :human_conditions
33
+ @@human_conditions = false
34
+
30
35
  # instance-level configuration
31
36
  # ----------------------------
32
37
 
@@ -54,8 +59,8 @@ module ActiveScaffold::Config
54
59
  attr_accessor :link
55
60
 
56
61
  # rarely searched columns may be placed in a hidden subgroup
57
- def optional_columns=(optionals)
58
- @optional_columns= Array(optionals)
62
+ def optional_columns=(optionals)
63
+ @optional_columns = Array(optionals)
59
64
  end
60
65
 
61
66
  def optional_columns
@@ -4,8 +4,9 @@ module ActiveScaffold::Config
4
4
  super
5
5
  # start with the ActionLink defined globally
6
6
  @link = self.class.link.clone unless self.class.link.nil?
7
- @action_group = self.class.action_group.clone if self.class.action_group
8
7
  @show_unauthorized_columns = self.class.show_unauthorized_columns
8
+ @refresh_list = self.class.refresh_list
9
+ @persistent = self.class.persistent
9
10
 
10
11
  # no global setting here because multipart should only be set for specific forms
11
12
  @multipart = false
@@ -16,6 +17,14 @@ module ActiveScaffold::Config
16
17
  # show value of unauthorized columns instead of skip them
17
18
  class_attribute :show_unauthorized_columns
18
19
 
20
+ # whether the form stays open after an update or not
21
+ cattr_accessor :persistent
22
+ @@persistent = false
23
+
24
+ # whether we should refresh list after update or not
25
+ cattr_accessor :refresh_list
26
+ @@refresh_list = false
27
+
19
28
  # instance-level configuration
20
29
  # ----------------------------
21
30
 
@@ -28,6 +37,12 @@ module ActiveScaffold::Config
28
37
  # the label for this Form action. used for the header.
29
38
  attr_writer :label
30
39
 
40
+ # whether the form stays open after a create or not
41
+ attr_accessor :persistent
42
+
43
+ # whether we should refresh list after create or not
44
+ attr_accessor :refresh_list
45
+
31
46
  # provides access to the list of columns specifically meant for the Form to use
32
47
  def columns
33
48
  unless @columns # lazy evaluation
@@ -18,10 +18,12 @@ module ActiveScaffold::Config
18
18
  @empty_field_text = self.class.empty_field_text
19
19
  @association_join_text = self.class.association_join_text
20
20
  @pagination = self.class.pagination
21
- @show_search_reset = true
21
+ @show_search_reset = self.class.show_search_reset
22
22
  @reset_link = self.class.reset_link.clone
23
23
  @mark_records = self.class.mark_records
24
24
  @wrap_tag = self.class.wrap_tag
25
+ @always_show_search = self.class.always_show_search
26
+ @always_show_create = self.class.always_show_create
25
27
  end
26
28
 
27
29
  # global level configuration
@@ -62,9 +64,14 @@ module ActiveScaffold::Config
62
64
 
63
65
  # Add a checkbox in front of each record to mark them and use them with a batch action later
64
66
  cattr_accessor :mark_records
67
+ @@mark_records = false
68
+
69
+ # show a link to reset the search next to filtered message
70
+ cattr_accessor :show_search_reset
71
+ @@show_search_reset = true
65
72
 
66
73
  # the ActionLink to reset search
67
- cattr_accessor :reset_link
74
+ cattr_reader :reset_link
68
75
  @@reset_link = ActiveScaffold::DataStructures::ActionLink.new('index', :label => :click_to_reset, :type => :collection, :position => false)
69
76
 
70
77
  # wrap normal cells (not inplace editable columns or with link) with a tag
@@ -72,6 +79,14 @@ module ActiveScaffold::Config
72
79
  cattr_accessor :wrap_tag
73
80
  @@wrap_tag = nil
74
81
 
82
+ # Show search form in the list header instead of display the link
83
+ cattr_accessor :always_show_search
84
+ @@always_show_search = false
85
+
86
+ # Show create form in the list header instead of display the link
87
+ cattr_accessor :always_show_create
88
+ @@always_show_create = false
89
+
75
90
  # instance-level configuration
76
91
  # ----------------------------
77
92
 
@@ -5,8 +5,7 @@ module ActiveScaffold::Config
5
5
  def initialize(core_config)
6
6
  super
7
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
8
+ @shallow_delete = self.class.shallow_delete
10
9
  end
11
10
 
12
11
  # global level configuration
@@ -10,7 +10,6 @@ module ActiveScaffold::Config
10
10
 
11
11
  # start with the ActionLink defined globally
12
12
  @link = self.class.link.clone
13
- @action_group = self.class.action_group.clone if self.class.action_group
14
13
  end
15
14
 
16
15
 
@@ -35,6 +34,9 @@ module ActiveScaffold::Config
35
34
  @@live
36
35
  end
37
36
 
37
+ cattr_accessor :split_terms
38
+ @@split_terms = " "
39
+
38
40
  # instance-level configuration
39
41
  # ----------------------------
40
42
 
@@ -57,8 +59,6 @@ module ActiveScaffold::Config
57
59
  # Default is :full
58
60
  attr_accessor :text_search
59
61
 
60
- @@split_terms = " "
61
- cattr_accessor :split_terms
62
62
  attr_accessor :split_terms
63
63
 
64
64
  # the ActionLink for this action
@@ -6,7 +6,6 @@ module ActiveScaffold::Config
6
6
  super
7
7
  # start with the ActionLink defined globally
8
8
  @link = self.class.link.clone
9
- @action_group = self.class.action_group.clone if self.class.action_group
10
9
  end
11
10
 
12
11
  # global level configuration
@@ -4,7 +4,6 @@ module ActiveScaffold::Config
4
4
  def initialize(core_config)
5
5
  super
6
6
  self.nested_links = self.class.nested_links
7
- self.refresh_list = self.class.refresh_list
8
7
  end
9
8
 
10
9
  # global level configuration
@@ -18,14 +17,6 @@ module ActiveScaffold::Config
18
17
  end
19
18
  @@link = ActiveScaffold::DataStructures::ActionLink.new('edit', :label => :edit, :type => :member, :security_method => :update_authorized?)
20
19
 
21
- # whether the form stays open after an update or not
22
- cattr_accessor :persistent
23
- @@persistent = false
24
-
25
- # whether we should refresh list after update or not
26
- cattr_accessor :refresh_list
27
- @@refresh_list = false
28
-
29
20
  # instance-level configuration
30
21
  # ----------------------------
31
22
 
@@ -33,16 +24,10 @@ module ActiveScaffold::Config
33
24
  cattr_accessor :nested_links
34
25
  @@nested_links = false
35
26
 
36
- # whether the form stays open after an update or not
37
- attr_accessor :persistent
38
-
39
27
  attr_writer :hide_nested_column
40
28
  def hide_nested_column
41
29
  @hide_nested_column.nil? ? true : @hide_nested_column
42
30
  end
43
-
44
- # whether we should refresh list after update or not
45
- attr_accessor :refresh_list
46
31
 
47
32
  end
48
33
  end
@@ -12,9 +12,13 @@ module ActiveScaffold
12
12
  # This lets the ActionColumns object skip constrained columns.
13
13
  #
14
14
  # 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.
15
- def register_constraints_with_action_columns(exclude_actions = [])
16
- constrained_fields = active_scaffold_constraints.reject{|k, v| v.is_a? Hash}.keys.collect{|k| k.to_sym}
15
+ def register_constraints_with_action_columns(constrained_fields = nil)
16
+ constrained_fields ||= []
17
+ constrained_fields |= active_scaffold_constraints.reject{|k, v| v.is_a? Hash}.keys.collect(&:to_sym)
18
+ exclude_actions = []
17
19
  exclude_actions << :list unless active_scaffold_config.list.hide_nested_column
20
+ exclude_actions << :update unless active_scaffold_config.update.hide_nested_column
21
+
18
22
  if self.class.uses_active_scaffold?
19
23
  # we actually want to do this whether constrained_fields exist or not, so that we can reset the array when they don't
20
24
  active_scaffold_config.actions.each do |action_name|
@@ -34,10 +38,11 @@ module ActiveScaffold
34
38
  # All of this work is primarily to support nested scaffolds in a manner generally useful for other
35
39
  # embedded scaffolds.
36
40
  def conditions_from_constraints
37
- conditions = nil
41
+ hash_conditions = {}
42
+ conditions = [hash_conditions]
38
43
  active_scaffold_constraints.each do |k, v|
39
44
  column = active_scaffold_config.columns[k]
40
- constraint_condition = if column
45
+ if column
41
46
  # Assume this is a multi-level association constraint.
42
47
  # example:
43
48
  # data model: Park -> Den -> Bear
@@ -47,8 +52,8 @@ module ActiveScaffold
47
52
  field = far_association.klass.primary_key
48
53
  table = far_association.table_name
49
54
 
50
- active_scaffold_includes.concat([{k => v.keys.first}]) # e.g. {:den => :park}
51
- constraint_condition_for("#{table}.#{field}", v.values.first)
55
+ active_scaffold_includes.concat([{k => far_association.name}]) # e.g. {:den => :park}
56
+ hash_conditions.merge!("#{table}.#{field}" => v.values.first)
52
57
 
53
58
  # association column constraint
54
59
  elsif column.association
@@ -57,23 +62,20 @@ module ActiveScaffold
57
62
  else
58
63
  active_scaffold_includes.concat column.includes
59
64
  end
60
- condition_from_association_constraint(column.association, v)
65
+ hash_conditions.merge!(condition_from_association_constraint(column.association, v))
61
66
 
62
67
  # regular column constraints
63
- elsif column.searchable?
68
+ elsif column.searchable? && params[column.name] != v
64
69
  active_scaffold_includes.concat column.includes
65
- constraint_condition_for(column.search_sql, v)
70
+ conditions << ["#{column.search_sql} = ?", v]
66
71
  end
67
72
  # unknown-to-activescaffold-but-real-database-column constraint
68
- elsif active_scaffold_config.model.column_names.include? k.to_s
69
- constraint_condition_for(k.to_s, v)
73
+ elsif active_scaffold_config.model.columns_hash[k.to_s] && params[column.name] != v
74
+ hash_conditions.merge!(k => v)
70
75
  else
71
76
  raise ActiveScaffold::MalformedConstraint, constraint_error(active_scaffold_config.model, k), caller
72
77
  end
73
-
74
- conditions = merge_conditions(conditions, constraint_condition)
75
78
  end
76
-
77
79
  conditions
78
80
  end
79
81
 
@@ -108,22 +110,19 @@ module ActiveScaffold
108
110
  value = association.klass.find(value).send(association.options[:primary_key])
109
111
  end
110
112
 
111
- condition = constraint_condition_for("#{table}.#{field}", value)
113
+ condition = {"#{table}.#{field}" => value}
112
114
  if association.options[:polymorphic]
113
- begin
114
- parent_scaffold = "#{session_info[:parent_scaffold].to_s.camelize}Controller".constantize
115
- condition = merge_conditions(
116
- condition,
117
- constraint_condition_for("#{table}.#{association.name}_type", parent_scaffold.active_scaffold_config.model_id.to_s)
118
- )
119
- rescue ActiveScaffold::ControllerNotFound
120
- nil
121
- end
115
+ raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(association), caller unless params[:parent_model]
116
+ condition["#{table}.#{association.name}_type"] = params[:parent_model].constantize.model.to_s
122
117
  end
123
118
 
124
119
  condition
125
120
  end
126
121
 
122
+ def polymorphic_constraint_error(association)
123
+ "Malformed constraint. You have added a constraint for #{association.name} polymorphic association but parent_model is not set."
124
+ end
125
+
127
126
  def constraint_error(klass, column_name)
128
127
  "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."
129
128
  end
@@ -145,6 +144,7 @@ module ActiveScaffold
145
144
  if column.plural_association?
146
145
  record.send("#{k}").send(:<<, column.association.klass.find(v))
147
146
  elsif column.association.options[:polymorphic]
147
+ raise ActiveScaffold::MalformedConstraint, polymorphic_constraint_error(column.association), caller unless params[:parent_model]
148
148
  record.send("#{k}=", params[:parent_model].constantize.find(v))
149
149
  else # regular singular association
150
150
  record.send("#{k}=", column.association.klass.find(v))
@@ -164,11 +164,5 @@ module ActiveScaffold
164
164
  end
165
165
  end
166
166
  end
167
-
168
- private
169
-
170
- def constraint_condition_for(sql, value)
171
- value.nil? ? "#{sql} IS NULL" : ["#{sql} = ?", value]
172
- end
173
167
  end
174
168
  end
@@ -317,7 +317,7 @@ module ActiveScaffold::DataStructures
317
317
  # just the field (not table.field)
318
318
  def field_name
319
319
  return nil if virtual?
320
- column ? @active_record_class.connection.quote_column_name(column.name) : association.foreign_key
320
+ @field_name ||= column ? @active_record_class.connection.quote_column_name(column.name) : association.foreign_key
321
321
  end
322
322
 
323
323
  def <=>(other_column)
@@ -356,7 +356,7 @@ module ActiveScaffold::DataStructures
356
356
  self.sort = {:method => "#{self.name}.to_s"}
357
357
  elsif self.plural_association?
358
358
  self.sort = {:method => "#{self.name}.join(',')"}
359
- else
359
+ elsif @active_record_class.connection
360
360
  self.sort = {:sql => self.field}
361
361
  end
362
362
  end
@@ -365,11 +365,9 @@ module ActiveScaffold::DataStructures
365
365
  def initialize_search_sql
366
366
  self.search_sql = unless self.virtual?
367
367
  if association.nil?
368
- self.field.to_s
368
+ self.field.to_s unless @active_record_class.connection.nil?
369
369
  elsif !self.polymorphic_association?
370
- [association.klass.table_name, association.klass.primary_key].collect! do |str|
371
- association.klass.connection.quote_column_name str
372
- end.join('.')
370
+ [association.klass.quoted_table_name, association.klass.quoted_primary_key].join('.') unless association.klass.connection.nil?
373
371
  end
374
372
  end
375
373
  end
@@ -379,7 +377,7 @@ module ActiveScaffold::DataStructures
379
377
 
380
378
  # the table.field name for this column, if applicable
381
379
  def field
382
- @field ||= [@active_record_class.connection.quote_table_name(@table), field_name].join('.')
380
+ @field ||= [@active_record_class.quoted_table_name, field_name].join('.')
383
381
  end
384
382
 
385
383
  def estimate_weight
@@ -19,7 +19,7 @@ module ActiveScaffold::DataStructures
19
19
  end
20
20
  end
21
21
 
22
- attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :constrained_fields, :constraints, :scope
22
+ attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :constrained_fields, :scope
23
23
 
24
24
  def initialize(model, nested_info)
25
25
  @parent_model = nested_info[:parent_model]
@@ -108,16 +108,16 @@ module ActiveScaffold::DataStructures
108
108
  protected
109
109
 
110
110
  def iterate_model_associations(model)
111
- @constraints = {}
112
- @constraints[association.foreign_key.to_sym] = parent_id unless association.belongs_to?
111
+ @constrained_fields = Set.new
112
+ constrained_fields << association.foreign_key.to_sym unless association.belongs_to?
113
113
  model.reflect_on_all_associations.each do |current|
114
114
  if !current.belongs_to? && association.foreign_key == current.association_foreign_key
115
- constraints[current.name.to_sym] = parent_id
115
+ constrained_fields << current.name.to_sym
116
116
  @child_association = current if current.klass == @parent_model
117
117
  end
118
118
  if association.foreign_key == current.foreign_key
119
119
  # show columns for has_many and has_one child associationes
120
- constraints[current.name.to_sym] = parent_id if current.belongs_to?
120
+ constrained_fields << current.name.to_sym if current.belongs_to?
121
121
  if association.options[:as] and current.options[:polymorphic]
122
122
  @child_association = current if association.options[:as].to_sym == current.name
123
123
  else
@@ -125,7 +125,7 @@ module ActiveScaffold::DataStructures
125
125
  end
126
126
  end
127
127
  end
128
- @constrained_fields = @constraints.keys
128
+ @constrained_fields = @constrained_fields.to_a
129
129
  end
130
130
  end
131
131
 
@@ -4,6 +4,10 @@ module ActiveScaffold::DataStructures
4
4
  include ActiveScaffold::Configurable
5
5
 
6
6
  def initialize(*args)
7
+ set_values(*args)
8
+ end
9
+
10
+ def set_values(*args)
7
11
  @set = []
8
12
  self.add *args
9
13
  end
@@ -19,14 +19,13 @@ module ActiveScaffold
19
19
  columns.each do |column|
20
20
  where_clauses << ((column.column.nil? || column.column.text?) ? "#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?" : "#{column.search_sql} = ?")
21
21
  end
22
- phrase = "(#{where_clauses.join(' OR ')})"
22
+ phrase = where_clauses.join(' OR ')
23
23
 
24
- sql = ([phrase] * tokens.length).join(' AND ')
25
- tokens = tokens.collect do |value|
26
- columns.collect {|column| (column.column.nil? || column.column.text?) ? like_pattern.sub('?', value) : column.column.type_cast(value)}
27
- end.flatten
28
-
29
- [sql, *tokens]
24
+ tokens.collect do |value|
25
+ columns.inject([phrase]) do |condition, column|
26
+ condition.push((column.column.nil? || column.column.text?) ? like_pattern.sub('?', value) : column.column.type_cast(value))
27
+ end
28
+ end
30
29
  end
31
30
 
32
31
  # Generates an SQL condition for the given ActiveScaffold column based on
@@ -247,13 +246,13 @@ module ActiveScaffold
247
246
  end
248
247
 
249
248
  def all_conditions
250
- merge_conditions(
249
+ [
251
250
  active_scaffold_conditions, # from the search modules
252
251
  conditions_for_collection, # from the dev
253
252
  conditions_from_params, # from the parameters (e.g. /users/list?first_name=Fred)
254
253
  conditions_from_constraints, # from any constraints (embedded scaffolds)
255
254
  active_scaffold_session_storage[:conditions] # embedding conditions (weaker constraints)
256
- )
255
+ ]
257
256
  end
258
257
 
259
258
  # returns a single record (the given id) but only if it's allowed for the specified action.
@@ -264,8 +263,6 @@ module ActiveScaffold
264
263
  raise ActiveScaffold::RecordNotAllowed, "#{klass} with id = #{id}" unless record.authorized_for?(:crud_type => crud_type.to_sym)
265
264
  return record
266
265
  end
267
-
268
- # returns a hash with options to find records
269
266
  # valid options may include:
270
267
  # * :sorting - a Sorting DataStructure (basically an array of hashes of field => direction, e.g. [{:field1 => 'asc'}, {:field2 => 'desc'}]). please note that multi-column sorting has some limitations: if any column in a multi-field sort uses method-based sorting, it will be ignored. method sorting only works for single-column sorting.
271
268
  # * :per_page
@@ -276,10 +273,10 @@ module ActiveScaffold
276
273
 
277
274
  # create a general-use options array that's compatible with Rails finders
278
275
  finder_options = { :reorder => options[:sorting].try(:clause),
279
- :where => search_conditions,
276
+ :conditions => search_conditions,
280
277
  :joins => joins_for_finder,
281
278
  :includes => full_includes}
282
-
279
+
283
280
  finder_options.merge! custom_finder_options
284
281
  finder_options
285
282
  end
@@ -330,7 +327,8 @@ module ActiveScaffold
330
327
  end
331
328
 
332
329
  def append_to_query(query, options)
333
- options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :includes, :lock, :readonly, :from
330
+ options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :includes, :lock, :readonly, :from, :conditions
331
+ query = apply_conditions(query, *options.delete(:conditions)) if options[:conditions]
334
332
  options.reject{|k, v| v.blank?}.inject(query) do |query, (k, v)|
335
333
  query.send((k.to_sym), v)
336
334
  end
@@ -347,15 +345,14 @@ module ActiveScaffold
347
345
  end + active_scaffold_habtm_joins
348
346
  end
349
347
 
350
- def merge_conditions(*conditions)
351
- segments = []
352
- conditions.each do |condition|
353
- unless condition.blank?
354
- sql = active_scaffold_config.model.send(:sanitize_sql, condition)
355
- segments << sql unless sql.blank?
348
+ def apply_conditions(query, *conditions)
349
+ conditions.reject(&:blank?).inject(query) do |query, condition|
350
+ if condition.is_a?(Array) && !condition.first.is_a?(String) # multiple conditions
351
+ apply_conditions(query, *condition)
352
+ else
353
+ query.where(condition)
356
354
  end
357
355
  end
358
- "(#{segments.join(') AND (')})" unless segments.empty?
359
356
  end
360
357
 
361
358
  # TODO: this should reside on the column, not the controller
@@ -2,7 +2,7 @@ module ActiveScaffold
2
2
  module Version
3
3
  MAJOR = 3
4
4
  MINOR = 2
5
- PATCH = 8
5
+ PATCH = 9
6
6
 
7
7
  STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
8
  end
@@ -8,4 +8,3 @@ ActionView::Base.send(:include, ActiveScaffold::Helpers::ViewHelpers)
8
8
 
9
9
  ActionController::Base.class_eval {include ActiveRecordPermissions::ModelUserAccess::Controller}
10
10
  ActiveRecord::Base.class_eval {include ActiveRecordPermissions::ModelUserAccess::Model}
11
- ActiveRecord::Base.class_eval {include ActiveRecordPermissions::Permissions}
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 2
9
- - 8
10
- version: 3.2.8
9
+ - 9
10
+ version: 3.2.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Many, see README
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-17 00:00:00 Z
18
+ date: 2012-05-22 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :development