active_scaffold 3.3.0.rc3 → 3.3.0
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 +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|
|