active_scaffold 3.3.0.rc3 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +16 -4
- data/README.md +67 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +9 -9
- data/app/views/active_scaffold_overrides/_form.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_form_association.html.erb +3 -2
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +6 -4
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +4 -0
- data/app/views/active_scaffold_overrides/_render_field.js.erb +3 -2
- data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +1 -1
- data/app/views/active_scaffold_overrides/edit_associated.js.erb +1 -1
- data/app/views/active_scaffold_overrides/on_create.js.erb +2 -1
- data/app/views/active_scaffold_overrides/render_field_inplace.html.erb +6 -1
- data/config/locales/ru.yml +6 -6
- data/lib/active_scaffold/actions/core.rb +2 -2
- data/lib/active_scaffold/actions/create.rb +1 -0
- data/lib/active_scaffold/actions/field_search.rb +4 -5
- data/lib/active_scaffold/actions/list.rb +13 -13
- data/lib/active_scaffold/actions/mark.rb +1 -1
- data/lib/active_scaffold/actions/search.rb +2 -2
- data/lib/active_scaffold/actions/show.rb +3 -3
- data/lib/active_scaffold/actions/subform.rb +2 -1
- data/lib/active_scaffold/actions/update.rb +1 -0
- data/lib/active_scaffold/attribute_params.rb +6 -2
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +4 -1
- data/lib/active_scaffold/bridges/calendar_date_select.rb +1 -1
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +2 -2
- data/lib/active_scaffold/bridges/date_picker/helper.rb +1 -1
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +2 -2
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +2 -2
- data/lib/active_scaffold/bridges/file_column.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +2 -2
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip.rb +1 -1
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -1
- data/lib/active_scaffold/config/list.rb +9 -1
- data/lib/active_scaffold/constraints.rb +2 -2
- data/lib/active_scaffold/data_structures/action_columns.rb +2 -2
- data/lib/active_scaffold/data_structures/action_links.rb +3 -3
- data/lib/active_scaffold/data_structures/column.rb +16 -1
- data/lib/active_scaffold/extensions/action_view_rendering.rb +17 -5
- data/lib/active_scaffold/extensions/left_outer_joins.rb +33 -0
- data/lib/active_scaffold/extensions/paginator_extensions.rb +8 -0
- data/lib/active_scaffold/extensions/unsaved_associated.rb +4 -4
- data/lib/active_scaffold/finder.rb +13 -7
- data/lib/active_scaffold/helpers/controller_helpers.rb +11 -1
- data/lib/active_scaffold/helpers/form_column_helpers.rb +50 -27
- data/lib/active_scaffold/helpers/list_column_helpers.rb +9 -3
- data/lib/active_scaffold/helpers/view_helpers.rb +8 -8
- data/lib/active_scaffold/tableless.rb +8 -0
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold.rb +1 -0
- data/lib/generators/active_scaffold_controller/templates/controller.rb +7 -1
- metadata +7 -10
- data/README +0 -66
- data/app/views/active_scaffold_overrides/_form_attribute.html.erb +0 -27
- data/app/views/active_scaffold_overrides/_form_hidden_attribute.html.erb +0 -7
@@ -2,7 +2,7 @@ module ActiveScaffold
|
|
2
2
|
module Helpers
|
3
3
|
module FormColumnHelpers
|
4
4
|
def active_scaffold_input_carrierwave(column, options)
|
5
|
-
options = active_scaffold_input_text_options(options)
|
5
|
+
options = active_scaffold_input_text_options(options.merge(column.options))
|
6
6
|
carrierwave = @record.send("#{column.name}")
|
7
7
|
if !carrierwave.file.blank?
|
8
8
|
|
@@ -42,4 +42,4 @@ module ActiveScaffold
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
-
end
|
45
|
+
end
|
@@ -71,7 +71,7 @@ module ActiveScaffold::Bridges
|
|
71
71
|
|
72
72
|
def self.datetime_options(locale)
|
73
73
|
begin
|
74
|
-
rails_time_format = I18n.translate! 'time.formats.picker', :locale => locale
|
74
|
+
rails_time_format = I18n.translate! 'time.formats.picker', :locale => locale, :default => '%a, %d %b %Y %H:%M:%S'
|
75
75
|
datetime_picker_options = {:ampm => false,
|
76
76
|
:hourText => I18n.translate!('datetime.prompts.hour', :locale => locale),
|
77
77
|
:minuteText => I18n.translate!('datetime.prompts.minute', :locale => locale),
|
@@ -2,7 +2,7 @@ module ActiveScaffold
|
|
2
2
|
module Helpers
|
3
3
|
module FormColumnHelpers
|
4
4
|
def active_scaffold_input_dragonfly(column, options)
|
5
|
-
options = active_scaffold_input_text_options(options)
|
5
|
+
options = active_scaffold_input_text_options(options.merge(column.options))
|
6
6
|
input = file_field(:record, column.name, options)
|
7
7
|
dragonfly = @record.send("#{column.name}")
|
8
8
|
if dragonfly.present?
|
@@ -24,4 +24,4 @@ module ActiveScaffold
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
@@ -24,7 +24,7 @@ module ActiveScaffold::Config
|
|
24
24
|
}
|
25
25
|
end
|
26
26
|
|
27
|
-
alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column")
|
27
|
+
alias_method_chain :initialize, :file_column unless self.instance_methods.include?("initialize_without_file_column".send(::ActiveScaffold::METHOD_CONVERSION))
|
28
28
|
|
29
29
|
def configure_file_column_field(field)
|
30
30
|
# set list_ui first because it gets its default value from form_ui
|
@@ -4,12 +4,12 @@ module ActiveScaffold
|
|
4
4
|
module FileColumnHelpers
|
5
5
|
class << self
|
6
6
|
def file_column_fields(klass)
|
7
|
-
klass.instance_methods.
|
7
|
+
klass.instance_methods.select{|m| m.to_s =~ /_just_uploaded\?$/}.collect{|m| m[0..-16].to_sym }
|
8
8
|
end
|
9
9
|
|
10
10
|
def generate_delete_helpers(klass)
|
11
11
|
file_column_fields(klass).each { |field|
|
12
|
-
klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=")
|
12
|
+
klass.send :class_eval, <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("#{field}_with_delete=".send(::ActiveScaffold::METHOD_CONVERSION))
|
13
13
|
attr_reader :delete_#{field}
|
14
14
|
|
15
15
|
def delete_#{field}=(value)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class ActiveScaffold::Bridges::FileColumn < ActiveScaffold::DataStructures::Bridge
|
2
2
|
def self.install
|
3
|
-
if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column")
|
3
|
+
if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_file_column".send(::ActiveScaffold::METHOD_CONVERSION))
|
4
4
|
raise RuntimeError, "We've detected that you have active_scaffold_file_column_bridge installed. This plugin has been moved to core. Please remove active_scaffold_file_column_bridge to prevent any conflicts"
|
5
5
|
end
|
6
6
|
require File.join(File.dirname(__FILE__), "file_column/as_file_column_bridge")
|
@@ -2,7 +2,7 @@ module ActiveScaffold
|
|
2
2
|
module Helpers
|
3
3
|
module FormColumnHelpers
|
4
4
|
def active_scaffold_input_paperclip(column, options)
|
5
|
-
options = active_scaffold_input_text_options(options)
|
5
|
+
options = active_scaffold_input_text_options(options.merge(column.options))
|
6
6
|
input = file_field(:record, column.name, options)
|
7
7
|
paperclip = @record.send("#{column.name}")
|
8
8
|
if paperclip.file?
|
@@ -24,4 +24,4 @@ module ActiveScaffold
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
@@ -6,7 +6,7 @@ module ActiveScaffold
|
|
6
6
|
self.thumbnail_style = :thumbnail
|
7
7
|
|
8
8
|
def self.generate_delete_helper(klass, field)
|
9
|
-
klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.instance_methods.include?("delete_#{field}=")
|
9
|
+
klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.instance_methods.include?("delete_#{field}=".send(::ActiveScaffold::METHOD_CONVERSION))
|
10
10
|
attr_reader :delete_#{field}
|
11
11
|
|
12
12
|
def delete_#{field}=(value)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class ActiveScaffold::Bridges::Paperclip < ActiveScaffold::DataStructures::Bridge
|
2
2
|
def self.install
|
3
|
-
if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip")
|
3
|
+
if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_paperclip".send(::ActiveScaffold::METHOD_CONVERSION))
|
4
4
|
raise RuntimeError, "We've detected that you have active_scaffold_paperclip_bridge installed. This plugin has been moved to core. Please remove active_scaffold_paperclip_bridge to prevent any conflicts"
|
5
5
|
end
|
6
6
|
require File.join(File.dirname(__FILE__), "paperclip/form_ui")
|
@@ -16,7 +16,7 @@ class ActiveScaffold::Bridges::TinyMce
|
|
16
16
|
options[:class] = "#{options[:class]} mceEditor #{column.options[:class]}".strip
|
17
17
|
|
18
18
|
settings = { :theme => 'simple' }.merge(column.options[:tinymce] || {})
|
19
|
-
|
19
|
+
settings = settings.to_json
|
20
20
|
settings = "tinyMCE.settings = #{settings};"
|
21
21
|
|
22
22
|
html = []
|
@@ -25,10 +25,15 @@ module ActiveScaffold::Config
|
|
25
25
|
@always_show_create = self.class.always_show_create
|
26
26
|
@messages_above_header = self.class.messages_above_header
|
27
27
|
@auto_select_columns = self.class.auto_select_columns
|
28
|
+
@refresh_with_header = self.class.refresh_with_header
|
28
29
|
end
|
29
30
|
|
30
31
|
# global level configuration
|
31
32
|
# --------------------------
|
33
|
+
# include list header on refresh
|
34
|
+
cattr_accessor :refresh_with_header
|
35
|
+
@@refresh_with_header = false
|
36
|
+
|
32
37
|
# how many records to show per page
|
33
38
|
cattr_accessor :per_page
|
34
39
|
@@per_page = 15
|
@@ -96,6 +101,9 @@ module ActiveScaffold::Config
|
|
96
101
|
|
97
102
|
public :columns=
|
98
103
|
|
104
|
+
# include list header on refresh
|
105
|
+
attr_accessor :refresh_with_header
|
106
|
+
|
99
107
|
# how many rows to show at once
|
100
108
|
attr_accessor :per_page
|
101
109
|
|
@@ -199,7 +207,7 @@ module ActiveScaffold::Config
|
|
199
207
|
attr_writer :label
|
200
208
|
# This label has alread been localized.
|
201
209
|
def label
|
202
|
-
@label || @conf.label
|
210
|
+
self[:label] || @label || @conf.label
|
203
211
|
end
|
204
212
|
|
205
213
|
def per_page
|
@@ -69,7 +69,7 @@ module ActiveScaffold
|
|
69
69
|
|
70
70
|
# regular column constraints
|
71
71
|
elsif column.searchable? && params[column.name] != v
|
72
|
-
active_scaffold_includes.concat column.includes
|
72
|
+
active_scaffold_includes.concat column.includes if column.includes.present?
|
73
73
|
conditions << [column.search_sql.collect { |search_sql| "#{search_sql} = ?" }.join(' OR '), *([v] * column.search_sql.size)]
|
74
74
|
end
|
75
75
|
# unknown-to-activescaffold-but-real-database-column constraint
|
@@ -79,7 +79,7 @@ module ActiveScaffold
|
|
79
79
|
raise ActiveScaffold::MalformedConstraint, constraint_error(active_scaffold_config.model, k), caller
|
80
80
|
end
|
81
81
|
end
|
82
|
-
conditions
|
82
|
+
conditions.reject(&:blank?)
|
83
83
|
end
|
84
84
|
|
85
85
|
# We do NOT want to use .search_sql. If anything, search_sql will refer
|
@@ -93,7 +93,7 @@ module ActiveScaffold::DataStructures
|
|
93
93
|
options[:for] ||= @columns.active_record_class
|
94
94
|
self.unauthorized_columns = []
|
95
95
|
@set.each do |item|
|
96
|
-
unless item.is_a? ActiveScaffold::DataStructures::ActionColumns
|
96
|
+
unless item.is_a? ActiveScaffold::DataStructures::ActionColumns || @columns.nil?
|
97
97
|
item = (@columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, @columns.active_record_class))
|
98
98
|
next if self.skip_column?(item, options)
|
99
99
|
end
|
@@ -111,7 +111,7 @@ module ActiveScaffold::DataStructures
|
|
111
111
|
# skip if this matches a constrained column
|
112
112
|
result = true if constraint_columns.include?(column.name.to_sym)
|
113
113
|
# skip this field if it's not authorized
|
114
|
-
unless options[:for].authorized_for?(:action => options[:action], :crud_type => options[:crud_type] || self.action.crud_type, :column => column.name)
|
114
|
+
unless options[:for].authorized_for?(:action => options[:action], :crud_type => options[:crud_type] || self.action.try(:crud_type), :column => column.name)
|
115
115
|
self.unauthorized_columns << column.name.to_sym
|
116
116
|
result = true
|
117
117
|
end
|
@@ -70,8 +70,8 @@ module ActiveScaffold::DataStructures
|
|
70
70
|
|
71
71
|
def delete(val)
|
72
72
|
self.each({:include_set => true}) do |link, set|
|
73
|
-
if link.action == val.to_s
|
74
|
-
set.
|
73
|
+
if link.action.to_s == val.to_s
|
74
|
+
set.delete link
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -79,7 +79,7 @@ module ActiveScaffold::DataStructures
|
|
79
79
|
def delete_group(name)
|
80
80
|
@set.each do |group|
|
81
81
|
if group.name == name
|
82
|
-
@set.
|
82
|
+
@set.delete group
|
83
83
|
else
|
84
84
|
group.delete_group(name)
|
85
85
|
end if group.is_a?(ActiveScaffold::DataStructures::ActionLinks)
|
@@ -174,6 +174,18 @@ module ActiveScaffold::DataStructures
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
|
+
# a collection of associations to do left join when this column is included on search
|
178
|
+
def search_joins
|
179
|
+
@search_joins || @includes
|
180
|
+
end
|
181
|
+
|
182
|
+
def search_joins=(value)
|
183
|
+
@search_joins = case value
|
184
|
+
when Array then value
|
185
|
+
else [value] # automatically convert to an array
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
177
189
|
# a collection of columns to load when eager loading is disabled, if it's nil all columns will be loaded
|
178
190
|
attr_accessor :select_associated_columns
|
179
191
|
|
@@ -335,7 +347,10 @@ module ActiveScaffold::DataStructures
|
|
335
347
|
|
336
348
|
@weight = estimate_weight
|
337
349
|
|
338
|
-
|
350
|
+
if association && !polymorphic_association?
|
351
|
+
self.includes = [association.name]
|
352
|
+
self.search_joins = self.includes.clone
|
353
|
+
end
|
339
354
|
end
|
340
355
|
|
341
356
|
# just the field (not table.field)
|
@@ -43,11 +43,23 @@ module ActionView::Helpers #:nodoc:
|
|
43
43
|
constraints = options[:constraints]
|
44
44
|
conditions = options[:conditions]
|
45
45
|
eid = Digest::MD5.hexdigest(params[:controller] + remote_controller.to_s + constraints.to_s + conditions.to_s)
|
46
|
-
eid_info = {}
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
eid_info = session["as:#{eid}"] ||= {}
|
47
|
+
if constraints
|
48
|
+
eid_info[:constraints] = constraints
|
49
|
+
else
|
50
|
+
eid_info.delete :constraints
|
51
|
+
end
|
52
|
+
if conditions
|
53
|
+
eid_info[:conditions] = conditions
|
54
|
+
else
|
55
|
+
eid_info.delete :conditions
|
56
|
+
end
|
57
|
+
if options[:label]
|
58
|
+
eid_info[:list] = {:label => options[:label]}
|
59
|
+
else
|
60
|
+
eid_info.delete :list
|
61
|
+
end
|
62
|
+
session.delete "as:#{eid}" if eid_info.empty?
|
51
63
|
options[:params] ||= {}
|
52
64
|
options[:params].merge! :eid => eid, :embedded => true
|
53
65
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActiveScaffold
|
2
|
+
module OuterJoins
|
3
|
+
def outer_joins(*assocs)
|
4
|
+
joins(outer_joins_sql(*assocs))
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
def outer_joins_sql(*assocs)
|
9
|
+
assocs.collect do |assoc|
|
10
|
+
if assoc.is_a? Array
|
11
|
+
outer_joins_sql(*assoc)
|
12
|
+
elsif assoc.is_a? Hash
|
13
|
+
assoc.collect do |key, val|
|
14
|
+
[left_outer_join_sql(key), klass.reflect_on_association(key).klass.outer_joins_sql(*val)]
|
15
|
+
end
|
16
|
+
elsif assoc.is_a? Symbol
|
17
|
+
left_outer_join_sql(assoc)
|
18
|
+
elsif assoc
|
19
|
+
assoc
|
20
|
+
end
|
21
|
+
end.flatten.compact
|
22
|
+
end
|
23
|
+
|
24
|
+
def left_outer_join_sql(association_name)
|
25
|
+
t = ActiveRecord::Associations::JoinDependency.new(klass, association_name, []).join_associations.first.join_relation(klass).arel
|
26
|
+
t.joins(t)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
ActiveRecord::Relation.send :include, ActiveScaffold::OuterJoins
|
31
|
+
module ActiveRecord::Querying
|
32
|
+
delegate :outer_joins, :outer_joins_sql, :to => :scoped
|
33
|
+
end
|
@@ -47,10 +47,10 @@ class ActiveRecord::Base
|
|
47
47
|
# returns false if any yield returns false.
|
48
48
|
# returns true otherwise, even when none of the associations have been instantiated. build wrapper methods accordingly.
|
49
49
|
def with_unsaved_associated
|
50
|
-
associations_for_update.all? do |
|
51
|
-
association_proxy =
|
52
|
-
if association_proxy
|
53
|
-
records = association_proxy
|
50
|
+
associations_for_update.all? do |assoc|
|
51
|
+
association_proxy = self.association(assoc.name)
|
52
|
+
if association_proxy.target.present?
|
53
|
+
records = association_proxy.target
|
54
54
|
records = [records] unless records.is_a? Array # convert singular associations into collections for ease of use
|
55
55
|
records.select {|r| r.unsaved? and not r.readonly?}.all? {|r| yield r} # must use select instead of find_all, which Rails overrides on association proxies for db access
|
56
56
|
else
|
@@ -292,6 +292,11 @@ module ActiveScaffold
|
|
292
292
|
@active_scaffold_habtm_joins ||= []
|
293
293
|
end
|
294
294
|
|
295
|
+
attr_writer :active_scaffold_outer_joins
|
296
|
+
def active_scaffold_outer_joins
|
297
|
+
@active_scaffold_outer_joins ||= []
|
298
|
+
end
|
299
|
+
|
295
300
|
def all_conditions
|
296
301
|
[
|
297
302
|
active_scaffold_conditions, # from the search modules
|
@@ -299,7 +304,7 @@ module ActiveScaffold
|
|
299
304
|
conditions_from_params, # from the parameters (e.g. /users/list?first_name=Fred)
|
300
305
|
conditions_from_constraints, # from any constraints (embedded scaffolds)
|
301
306
|
active_scaffold_session_storage[:conditions] # embedding conditions (weaker constraints)
|
302
|
-
]
|
307
|
+
].reject(&:blank?)
|
303
308
|
end
|
304
309
|
|
305
310
|
# returns a single record (the given id) but only if it's allowed for the specified security options.
|
@@ -324,6 +329,7 @@ module ActiveScaffold
|
|
324
329
|
finder_options = { :reorder => options[:sorting].try(:clause),
|
325
330
|
:conditions => search_conditions,
|
326
331
|
:joins => joins_for_finder,
|
332
|
+
:outer_joins => active_scaffold_outer_joins,
|
327
333
|
:includes => full_includes,
|
328
334
|
:select => options[:select]}
|
329
335
|
|
@@ -332,7 +338,7 @@ module ActiveScaffold
|
|
332
338
|
end
|
333
339
|
|
334
340
|
def count_items(find_options = {}, count_includes = nil)
|
335
|
-
count_includes ||= find_options[:includes] unless find_options[:conditions].
|
341
|
+
count_includes ||= find_options[:includes] unless find_options[:conditions].blank?
|
336
342
|
options = find_options.reject{|k,v| [:select, :reorder].include? k}
|
337
343
|
options[:includes] = count_includes
|
338
344
|
|
@@ -377,22 +383,22 @@ module ActiveScaffold
|
|
377
383
|
pager.page(options[:page])
|
378
384
|
end
|
379
385
|
|
380
|
-
def
|
386
|
+
def calculate_query
|
381
387
|
conditions = all_conditions
|
382
388
|
includes = active_scaffold_config.list.count_includes
|
383
|
-
includes ||= active_scaffold_includes unless conditions.
|
389
|
+
includes ||= active_scaffold_includes unless conditions.blank?
|
384
390
|
primary_key = active_scaffold_config.model.primary_key
|
385
|
-
subquery = append_to_query(beginning_of_chain, :conditions => conditions, :joins =>
|
391
|
+
subquery = append_to_query(beginning_of_chain, :conditions => conditions, :joins => joins_for_finder, :outer_joins => active_scaffold_outer_joins)
|
386
392
|
subquery = subquery.select(active_scaffold_config.columns[primary_key].field)
|
387
393
|
if includes
|
388
394
|
includes_relation = beginning_of_chain.includes(includes)
|
389
395
|
subquery = subquery.send(:apply_join_dependency, subquery, includes_relation.send(:construct_join_dependency_for_association_find))
|
390
396
|
end
|
391
|
-
|
397
|
+
active_scaffold_config.model.where(primary_key => subquery)
|
392
398
|
end
|
393
399
|
|
394
400
|
def append_to_query(query, options)
|
395
|
-
options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :includes, :lock, :readonly, :from, :conditions
|
401
|
+
options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :outer_joins, :includes, :lock, :readonly, :from, :conditions
|
396
402
|
query = apply_conditions(query, *options[:conditions]) if options[:conditions]
|
397
403
|
options.reject{|k, v| k == :conditions || v.blank?}.inject(query) do |query, (k, v)|
|
398
404
|
query.send((k.to_sym), v)
|
@@ -2,11 +2,21 @@ module ActiveScaffold
|
|
2
2
|
module Helpers
|
3
3
|
module ControllerHelpers
|
4
4
|
def self.included(controller)
|
5
|
-
controller.class_eval { helper_method :params_for, :conditions_from_params, :main_path_to_return, :render_parent?, :render_parent_options, :render_parent_action, :nested_singular_association?, :build_associated}
|
5
|
+
controller.class_eval { helper_method :params_for, :conditions_from_params, :main_path_to_return, :render_parent?, :render_parent_options, :render_parent_action, :nested_singular_association?, :build_associated, :generate_temporary_id, :generated_id}
|
6
6
|
end
|
7
7
|
|
8
8
|
include ActiveScaffold::Helpers::IdHelpers
|
9
9
|
|
10
|
+
def generate_temporary_id(record = nil, generated_id = nil)
|
11
|
+
(generated_id || (Time.now.to_f*1000).to_i.to_s).tap do |id|
|
12
|
+
(@temporary_ids ||= {})[record.class.name] = id if record
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def generated_id(record)
|
17
|
+
@temporary_ids[record.class.name] if record && @temporary_ids
|
18
|
+
end
|
19
|
+
|
10
20
|
def params_for(options = {})
|
11
21
|
# :adapter and :position are one-use rendering arguments. they should not propagate.
|
12
22
|
# :sort, :sort_direction, and :page are arguments that stored in the session. they need not propagate.
|
@@ -4,19 +4,17 @@ module ActiveScaffold
|
|
4
4
|
module FormColumnHelpers
|
5
5
|
# This method decides which input to use for the given column.
|
6
6
|
# It does not do any rendering. It only decides which method is responsible for rendering.
|
7
|
-
def active_scaffold_input_for(column, scope = nil, options =
|
8
|
-
options
|
7
|
+
def active_scaffold_input_for(column, scope = nil, options = nil)
|
8
|
+
options ||= active_scaffold_input_options(column, scope)
|
9
9
|
options = update_columns_options(column, scope, options)
|
10
10
|
active_scaffold_render_input(column, options)
|
11
11
|
end
|
12
12
|
|
13
|
-
alias form_column active_scaffold_input_for
|
14
|
-
|
15
13
|
def active_scaffold_render_input(column, options)
|
16
14
|
begin
|
17
15
|
# first, check if the dev has created an override for this specific field
|
18
16
|
if (method = override_form_field(column))
|
19
|
-
send(method, @record, options)
|
17
|
+
send(method, options[:object] || @record, options)
|
20
18
|
# second, check if the dev has specified a valid form_ui for this column
|
21
19
|
elsif column.form_ui and (method = override_input(column.form_ui))
|
22
20
|
send(method, column, options)
|
@@ -31,7 +29,7 @@ module ActiveScaffold
|
|
31
29
|
raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'"
|
32
30
|
end
|
33
31
|
elsif column.virtual?
|
34
|
-
options[:value] = format_number_value(@record.send(column.name), column.options) if column.number?
|
32
|
+
options[:value] = format_number_value((options[:object] || @record).send(column.name), column.options) if column.number?
|
35
33
|
active_scaffold_input_virtual(column, options)
|
36
34
|
|
37
35
|
else # regular model attribute column
|
@@ -48,7 +46,7 @@ module ActiveScaffold
|
|
48
46
|
options[:size] ||= ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS["size"]
|
49
47
|
end
|
50
48
|
options[:include_blank] = true if column.column.null and [:date, :datetime, :time].include?(column.column.type)
|
51
|
-
options[:value] = format_number_value(@
|
49
|
+
options[:value] = format_number_value((options[:object] || @raecord).send(column.name), column.options) if column.number?
|
52
50
|
text_field(:record, column.name, options.merge(column.options))
|
53
51
|
end
|
54
52
|
end
|
@@ -69,7 +67,7 @@ module ActiveScaffold
|
|
69
67
|
col_class = col_class.join(' ')
|
70
68
|
end
|
71
69
|
unless readonly and not @record.new_record? or not @record.authorized_for?(:crud_type => crud_type, :column => column.name)
|
72
|
-
|
70
|
+
render_column(column, @record, column_renders_as(column), scope, false, col_class)
|
73
71
|
else
|
74
72
|
options = active_scaffold_input_options(column, scope).except(:name)
|
75
73
|
options[:class] = "#{options[:class]} #{col_class}" if col_class
|
@@ -95,7 +93,7 @@ module ActiveScaffold
|
|
95
93
|
options[:placeholder] = column.placeholder if column.placeholder.present?
|
96
94
|
|
97
95
|
# Fix for keeping unique IDs in subform
|
98
|
-
id_control = "record_#{column.name}_#{[params[:eid], params[:id]].compact.join '_'}"
|
96
|
+
id_control = "record_#{column.name}_#{[params[:eid], params[:parent_id] || params[:id]].compact.join '_'}"
|
99
97
|
id_control += scope_id(scope) if scope
|
100
98
|
|
101
99
|
classes = "#{column.name}-input"
|
@@ -112,12 +110,13 @@ module ActiveScaffold
|
|
112
110
|
active_scaffold_config.send(@record.new_record? ? :create : :update)
|
113
111
|
end
|
114
112
|
if form_action && column.update_columns && (column.update_columns & form_action.columns.names).present?
|
115
|
-
url_params =
|
116
|
-
url_params
|
113
|
+
url_params = params_for(:action => 'render_field', :column => column.name, :id => @record.id)
|
114
|
+
url_params = url_params.except(:parent_scaffold, :association, nested.param_name) if nested? && scope
|
117
115
|
url_params[:eid] = params[:eid] if params[:eid]
|
118
116
|
if scope
|
119
117
|
url_params[:controller] = subform_controller.controller_path
|
120
118
|
url_params[:scope] = scope
|
119
|
+
url_params[:parent_id] = params[:parent_id] || params[:id]
|
121
120
|
end
|
122
121
|
|
123
122
|
options[:class] = "#{options[:class]} update_form".strip
|
@@ -131,6 +130,43 @@ module ActiveScaffold
|
|
131
130
|
def field_attributes(column, record)
|
132
131
|
{}
|
133
132
|
end
|
133
|
+
|
134
|
+
def render_column(column, record, renders_as, scope = nil, only_value = false, col_class = nil)
|
135
|
+
if override_form_field_partial?(column)
|
136
|
+
render :partial => override_form_field_partial(column), :locals => { :column => column, :only_value => only_value, :scope => scope, :col_class => col_class }
|
137
|
+
elsif renders_as == :field || override_form_field?(column)
|
138
|
+
form_attribute(column, record, scope, only_value)
|
139
|
+
elsif renders_as == :subform
|
140
|
+
render :partial => 'form_association', :locals => { :column => column, :scope => scope }
|
141
|
+
else
|
142
|
+
form_hidden_attribute(column, record, scope)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def form_attribute(column, record, scope = nil, only_value = false, col_class = nil)
|
147
|
+
column_options = active_scaffold_input_options(column, scope)
|
148
|
+
attributes = field_attributes(column, record)
|
149
|
+
attributes[:class] = "#{attributes[:class]} #{col_class}" if col_class.present?
|
150
|
+
field = unless only_value
|
151
|
+
active_scaffold_input_for column, scope, column_options.merge(:object => record)
|
152
|
+
else
|
153
|
+
content_tag(:span, get_column_value(@record, column), column_options.except(:name)) <<
|
154
|
+
hidden_field(:record, column.association ? column.association.foreign_key : column.name, column_options.merge(:object => record))
|
155
|
+
end
|
156
|
+
|
157
|
+
content_tag :dl, attributes do
|
158
|
+
%|<dt>#{label_tag column_options[:id], column.label}</dt><dd>#{field}
|
159
|
+
#{loading_indicator_tag(:action => :render_field, :id => params[:id]) if column.update_columns}
|
160
|
+
#{content_tag :span, column.description, :class => 'description' if column.description.present?}
|
161
|
+
</dd>|.html_safe
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def form_hidden_attribute(column, record, scope = nil)
|
166
|
+
%|<dl style="display: none;"><dt></dt><dd>
|
167
|
+
#{hidden_field :record, column.name, active_scaffold_input_options(column, scope).merge(:object => record)}
|
168
|
+
</dd></dl>|.html_safe
|
169
|
+
end
|
134
170
|
|
135
171
|
##
|
136
172
|
## Form input methods
|
@@ -156,7 +192,7 @@ module ActiveScaffold
|
|
156
192
|
select_options.unshift(associated) unless associated.nil? || select_options.include?(associated)
|
157
193
|
|
158
194
|
method = column.name
|
159
|
-
options = {:selected => associated.try(:id), :include_blank => as_(:_select_)}
|
195
|
+
options = {:selected => associated.try(:id), :include_blank => as_(:_select_), :object => html_options.delete(:object)}
|
160
196
|
|
161
197
|
html_options.update(column.options[:html_options] || {})
|
162
198
|
options.update(column.options)
|
@@ -210,7 +246,7 @@ module ActiveScaffold
|
|
210
246
|
end
|
211
247
|
|
212
248
|
def active_scaffold_input_enum(column, html_options)
|
213
|
-
options = { :selected => @record.send(column.name) }
|
249
|
+
options = { :selected => @record.send(column.name), :object => html_options.delete(:object) }
|
214
250
|
options_for_select = active_scaffold_enum_options(column).collect do |text, value|
|
215
251
|
active_scaffold_translated_option(column, text, value)
|
216
252
|
end
|
@@ -342,19 +378,6 @@ module ActiveScaffold
|
|
342
378
|
end
|
343
379
|
alias_method :override_input?, :override_input
|
344
380
|
|
345
|
-
def form_partial_for_column(column, renders_as = nil)
|
346
|
-
renders_as ||= column_renders_as(column)
|
347
|
-
if override_form_field_partial?(column)
|
348
|
-
override_form_field_partial(column)
|
349
|
-
elsif renders_as == :field or override_form_field?(column)
|
350
|
-
"form_attribute"
|
351
|
-
elsif renders_as == :subform
|
352
|
-
"form_association"
|
353
|
-
elsif renders_as == :hidden
|
354
|
-
"form_hidden_attribute"
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
381
|
def subform_partial_for_column(column)
|
359
382
|
subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform"
|
360
383
|
if override_subform_partial?(column, subform_partial)
|
@@ -373,7 +396,7 @@ module ActiveScaffold
|
|
373
396
|
return :subsection
|
374
397
|
elsif column.active_record_class.locking_column.to_s == column.name.to_s or column.form_ui == :hidden
|
375
398
|
return :hidden
|
376
|
-
elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform)
|
399
|
+
elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform) or override_form_field?(column)
|
377
400
|
return :field
|
378
401
|
else
|
379
402
|
return :subform
|
@@ -226,7 +226,9 @@ module ActiveScaffold
|
|
226
226
|
column = column.clone
|
227
227
|
column.options = column.options.clone
|
228
228
|
column.form_ui = :select if (column.association && column.form_ui.nil?)
|
229
|
-
|
229
|
+
options = active_scaffold_input_options(column)
|
230
|
+
options[:class] = "#{options[:class]} inplace_field"
|
231
|
+
content_tag(:div, active_scaffold_input_for(column, nil, options), :style => "display:none;", :class => inplace_edit_control_css_class).tap do
|
230
232
|
@record = old_record
|
231
233
|
end
|
232
234
|
end
|
@@ -300,12 +302,16 @@ module ActiveScaffold
|
|
300
302
|
:remote => true, :method => :get}
|
301
303
|
url_options = params_for(:action => :index, :page => 1,
|
302
304
|
:sort => column.name, :sort_direction => sort_direction)
|
303
|
-
link_to column
|
305
|
+
link_to column_heading_label(column), url_options, options
|
304
306
|
else
|
305
|
-
content_tag(:p, column
|
307
|
+
content_tag(:p, column_heading_label(column))
|
306
308
|
end
|
307
309
|
end
|
308
310
|
|
311
|
+
def column_heading_label(column)
|
312
|
+
column.label
|
313
|
+
end
|
314
|
+
|
309
315
|
def render_nested_view(action_links, record)
|
310
316
|
rendered = []
|
311
317
|
action_links.member.each do |link|
|