active_scaffold 3.2.8 → 3.2.9

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