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 +5 -1
- data/lib/active_scaffold/actions/core.rb +9 -13
- data/lib/active_scaffold/actions/create.rb +2 -8
- data/lib/active_scaffold/actions/field_search.rb +5 -9
- data/lib/active_scaffold/actions/nested.rb +2 -6
- data/lib/active_scaffold/actions/search.rb +1 -1
- data/lib/active_scaffold/actions/update.rb +0 -1
- data/lib/active_scaffold/active_record_permissions.rb +1 -0
- data/lib/active_scaffold/config/base.rb +7 -3
- data/lib/active_scaffold/config/create.rb +2 -14
- data/lib/active_scaffold/config/delete.rb +1 -2
- data/lib/active_scaffold/config/field_search.rb +8 -3
- data/lib/active_scaffold/config/form.rb +16 -1
- data/lib/active_scaffold/config/list.rb +17 -2
- data/lib/active_scaffold/config/nested.rb +1 -2
- data/lib/active_scaffold/config/search.rb +3 -3
- data/lib/active_scaffold/config/show.rb +0 -1
- data/lib/active_scaffold/config/update.rb +0 -15
- data/lib/active_scaffold/constraints.rb +24 -30
- data/lib/active_scaffold/data_structures/column.rb +5 -7
- data/lib/active_scaffold/data_structures/nested_info.rb +6 -6
- data/lib/active_scaffold/data_structures/set.rb +4 -0
- data/lib/active_scaffold/finder.rb +18 -21
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold_env.rb +0 -1
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
= 3.2.
|
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 =
|
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.
|
157
|
-
if
|
158
|
-
|
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 = {
|
170
|
-
|
171
|
-
|
172
|
-
model =
|
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
|
-
|
55
|
-
|
53
|
+
self.active_scaffold_conditions << search_condition
|
54
|
+
filtered_columns << active_scaffold_config.columns[key]
|
56
55
|
end
|
57
56
|
end
|
58
|
-
|
59
|
-
|
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
|
-
|
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
|
|
@@ -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
|
66
|
-
@columns.
|
67
|
-
|
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
|
-
#
|
32
|
-
|
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
|
-
@
|
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
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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
|
@@ -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(
|
16
|
-
constrained_fields
|
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
|
-
|
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
|
-
|
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 =>
|
51
|
-
|
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
|
-
|
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.
|
69
|
-
|
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 =
|
113
|
+
condition = {"#{table}.#{field}" => value}
|
112
114
|
if association.options[:polymorphic]
|
113
|
-
|
114
|
-
|
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
|
-
|
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.
|
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.
|
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, :
|
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
|
-
@
|
112
|
-
|
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
|
-
|
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
|
-
|
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 = @
|
128
|
+
@constrained_fields = @constrained_fields.to_a
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
@@ -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 =
|
22
|
+
phrase = where_clauses.join(' OR ')
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
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
|
-
:
|
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
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
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
|
data/lib/active_scaffold_env.rb
CHANGED
@@ -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:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 3.2.
|
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-
|
18
|
+
date: 2012-05-22 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
type: :development
|