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 +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
|