active_scaffold 3.2.18 → 3.2.19
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 +3 -0
- data/app/assets/images/active_scaffold/add.png +0 -0
- data/app/assets/images/active_scaffold/arrow_down.png +0 -0
- data/app/assets/images/active_scaffold/arrow_up.png +0 -0
- data/app/assets/images/active_scaffold/close.png +0 -0
- data/app/assets/images/active_scaffold/close_touch.png +0 -0
- data/app/assets/images/active_scaffold/config.png +0 -0
- data/app/assets/images/active_scaffold/cross.png +0 -0
- data/app/assets/images/active_scaffold/gears.png +0 -0
- data/app/assets/images/active_scaffold/indicator-small.gif +0 -0
- data/app/assets/images/active_scaffold/indicator.gif +0 -0
- data/app/assets/images/active_scaffold/magnifier.png +0 -0
- data/app/assets/javascripts/active_scaffold.js.erb +19 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +1113 -0
- data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +24 -0
- data/app/assets/javascripts/jquery/draggable_lists.js +27 -0
- data/app/assets/javascripts/jquery/jquery.editinplace.js +743 -0
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +7 -0
- data/app/assets/javascripts/prototype/active_scaffold.js +1107 -0
- data/app/assets/javascripts/prototype/dhtml_history.js +870 -0
- data/app/assets/javascripts/prototype/form_enhancements.js +117 -0
- data/app/assets/javascripts/prototype/rico_corner.js +370 -0
- data/app/assets/javascripts/prototype/tiny_mce_bridge.js +7 -0
- data/app/assets/stylesheets/active_scaffold-ie.css.scss +54 -0
- data/app/assets/stylesheets/active_scaffold.css.scss +14 -0
- data/app/assets/stylesheets/active_scaffold_colors.css.scss +395 -0
- data/app/assets/stylesheets/active_scaffold_extensions.css.erb +2 -0
- data/app/assets/stylesheets/active_scaffold_images.css.scss +40 -0
- data/app/assets/stylesheets/active_scaffold_layout.css +936 -0
- data/app/assets/stylesheets/blue-theme.css +74 -0
- data/config/locales/de.yml +125 -0
- data/config/locales/en.yml +127 -0
- data/config/locales/es.yml +128 -0
- data/config/locales/fr.yml +131 -0
- data/config/locales/hu.yml +126 -0
- data/config/locales/ja.yml +126 -0
- data/config/locales/ru.yml +135 -0
- data/frontends/default/views/_action_group.html.erb +24 -0
- data/frontends/default/views/_add_existing_form.html.erb +30 -0
- data/frontends/default/views/_base_form.html.erb +53 -0
- data/frontends/default/views/_create_form.html.erb +8 -0
- data/frontends/default/views/_create_form_on_list.html.erb +6 -0
- data/frontends/default/views/_field_search.html.erb +32 -0
- data/frontends/default/views/_form.html.erb +28 -0
- data/frontends/default/views/_form_association.html.erb +17 -0
- data/frontends/default/views/_form_association_footer.html.erb +47 -0
- data/frontends/default/views/_form_attribute.html.erb +23 -0
- data/frontends/default/views/_form_hidden_attribute.html.erb +7 -0
- data/frontends/default/views/_form_messages.html.erb +5 -0
- data/frontends/default/views/_horizontal_subform.html.erb +22 -0
- data/frontends/default/views/_horizontal_subform_footer.html.erb +0 -0
- data/frontends/default/views/_horizontal_subform_header.html.erb +11 -0
- data/frontends/default/views/_horizontal_subform_record.html.erb +43 -0
- data/frontends/default/views/_human_conditions.html.erb +1 -0
- data/frontends/default/views/_list.html.erb +18 -0
- data/frontends/default/views/_list_actions.html.erb +15 -0
- data/frontends/default/views/_list_calculations.html.erb +16 -0
- data/frontends/default/views/_list_column_headings.html.erb +12 -0
- data/frontends/default/views/_list_header.html.erb +10 -0
- data/frontends/default/views/_list_inline_adapter.html.erb +21 -0
- data/frontends/default/views/_list_messages.html.erb +28 -0
- data/frontends/default/views/_list_pagination.html.erb +11 -0
- data/frontends/default/views/_list_pagination_links.html.erb +9 -0
- data/frontends/default/views/_list_record.html.erb +13 -0
- data/frontends/default/views/_list_record_columns.html.erb +8 -0
- data/frontends/default/views/_list_with_header.html.erb +36 -0
- data/frontends/default/views/_messages.html.erb +10 -0
- data/frontends/default/views/_refresh_list.js.erb +1 -0
- data/frontends/default/views/_render_field.js.erb +20 -0
- data/frontends/default/views/_row.html.erb +1 -0
- data/frontends/default/views/_search.html.erb +34 -0
- data/frontends/default/views/_search_attribute.html.erb +10 -0
- data/frontends/default/views/_show.html.erb +8 -0
- data/frontends/default/views/_show_columns.html.erb +15 -0
- data/frontends/default/views/_update_actions.html.erb +9 -0
- data/frontends/default/views/_update_calculations.js.erb +4 -0
- data/frontends/default/views/_update_form.html.erb +6 -0
- data/frontends/default/views/_update_messages.js.erb +2 -0
- data/frontends/default/views/_vertical_subform.html.erb +12 -0
- data/frontends/default/views/_vertical_subform_record.html.erb +43 -0
- data/frontends/default/views/action_confirmation.html.erb +13 -0
- data/frontends/default/views/add_existing.js.erb +14 -0
- data/frontends/default/views/add_existing_form.html.erb +5 -0
- data/frontends/default/views/create.html.erb +5 -0
- data/frontends/default/views/delete.html.erb +13 -0
- data/frontends/default/views/destroy.js.erb +26 -0
- data/frontends/default/views/edit_associated.js.erb +12 -0
- data/frontends/default/views/field_search.html.erb +5 -0
- data/frontends/default/views/form_messages.js.erb +1 -0
- data/frontends/default/views/list.html.erb +1 -0
- data/frontends/default/views/on_action_update.js.erb +22 -0
- data/frontends/default/views/on_create.js.erb +38 -0
- data/frontends/default/views/on_mark.js.erb +6 -0
- data/frontends/default/views/on_update.js.erb +29 -0
- data/frontends/default/views/refresh_list.js.erb +2 -0
- data/frontends/default/views/render_field.js.erb +1 -0
- data/frontends/default/views/row.js.erb +2 -0
- data/frontends/default/views/search.html.erb +5 -0
- data/frontends/default/views/show.html.erb +5 -0
- data/frontends/default/views/update.html.erb +8 -0
- data/frontends/default/views/update_column.js.erb +15 -0
- data/frontends/default/views/update_row.js.erb +1 -0
- data/lib/active_scaffold/actions/common_search.rb +22 -0
- data/lib/active_scaffold/actions/core.rb +203 -0
- data/lib/active_scaffold/actions/create.rb +139 -0
- data/lib/active_scaffold/actions/delete.rb +74 -0
- data/lib/active_scaffold/actions/field_search.rb +78 -0
- data/lib/active_scaffold/actions/list.rb +208 -0
- data/lib/active_scaffold/actions/mark.rb +89 -0
- data/lib/active_scaffold/actions/nested.rb +244 -0
- data/lib/active_scaffold/actions/search.rb +48 -0
- data/lib/active_scaffold/actions/show.rb +61 -0
- data/lib/active_scaffold/actions/subform.rb +23 -0
- data/lib/active_scaffold/actions/update.rb +156 -0
- data/lib/active_scaffold/active_record_permissions.rb +135 -0
- data/lib/active_scaffold/attribute_params.rb +200 -0
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +39 -0
- data/lib/active_scaffold/bridges/ancestry.rb +5 -0
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +37 -0
- data/lib/active_scaffold/bridges/bitfields.rb +6 -0
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +66 -0
- data/lib/active_scaffold/bridges/calendar_date_select.rb +24 -0
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +127 -0
- data/lib/active_scaffold/bridges/cancan.rb +15 -0
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +31 -0
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge_helpers.rb +10 -0
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +45 -0
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +17 -0
- data/lib/active_scaffold/bridges/carrierwave.rb +12 -0
- data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +358 -0
- data/lib/active_scaffold/bridges/country_helper.rb +9 -0
- data/lib/active_scaffold/bridges/date_picker/ext.rb +63 -0
- data/lib/active_scaffold/bridges/date_picker/helper.rb +180 -0
- data/lib/active_scaffold/bridges/date_picker.rb +23 -0
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +34 -0
- data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge_helpers.rb +10 -0
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +27 -0
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +16 -0
- data/lib/active_scaffold/bridges/dragonfly.rb +9 -0
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +46 -0
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +57 -0
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +34 -0
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +26 -0
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +43 -0
- data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +9 -0
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +15 -0
- data/lib/active_scaffold/bridges/file_column.rb +11 -0
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +27 -0
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +16 -0
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +36 -0
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +24 -0
- data/lib/active_scaffold/bridges/paperclip.rb +12 -0
- data/lib/active_scaffold/bridges/record_select/helpers.rb +92 -0
- data/lib/active_scaffold/bridges/record_select.rb +11 -0
- data/lib/active_scaffold/bridges/semantic_attributes/column.rb +20 -0
- data/lib/active_scaffold/bridges/semantic_attributes.rb +5 -0
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +209 -0
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +46 -0
- data/lib/active_scaffold/bridges/tiny_mce.rb +17 -0
- data/lib/active_scaffold/bridges.rb +61 -0
- data/lib/active_scaffold/config/base.rb +75 -0
- data/lib/active_scaffold/config/core.rb +236 -0
- data/lib/active_scaffold/config/create.rb +32 -0
- data/lib/active_scaffold/config/delete.rb +32 -0
- data/lib/active_scaffold/config/field_search.rb +79 -0
- data/lib/active_scaffold/config/form.rb +64 -0
- data/lib/active_scaffold/config/list.rb +247 -0
- data/lib/active_scaffold/config/mark.rb +30 -0
- data/lib/active_scaffold/config/nested.rb +42 -0
- data/lib/active_scaffold/config/search.rb +73 -0
- data/lib/active_scaffold/config/show.rb +31 -0
- data/lib/active_scaffold/config/subform.rb +35 -0
- data/lib/active_scaffold/config/update.rb +33 -0
- data/lib/active_scaffold/configurable.rb +29 -0
- data/lib/active_scaffold/constraints.rb +171 -0
- data/lib/active_scaffold/data_structures/action_columns.rb +142 -0
- data/lib/active_scaffold/data_structures/action_link.rb +185 -0
- data/lib/active_scaffold/data_structures/action_links.rb +191 -0
- data/lib/active_scaffold/data_structures/actions.rb +45 -0
- data/lib/active_scaffold/data_structures/bridge.rb +22 -0
- data/lib/active_scaffold/data_structures/column.rb +402 -0
- data/lib/active_scaffold/data_structures/columns.rb +75 -0
- data/lib/active_scaffold/data_structures/error_message.rb +24 -0
- data/lib/active_scaffold/data_structures/nested_info.rb +171 -0
- data/lib/active_scaffold/data_structures/set.rb +61 -0
- data/lib/active_scaffold/data_structures/sorting.rb +167 -0
- data/lib/active_scaffold/engine.rb +4 -0
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +20 -0
- data/lib/active_scaffold/extensions/action_controller_rescueing.rb +7 -0
- data/lib/active_scaffold/extensions/action_view_rendering.rb +115 -0
- data/lib/active_scaffold/extensions/active_record_offset.rb +12 -0
- data/lib/active_scaffold/extensions/array.rb +7 -0
- data/lib/active_scaffold/extensions/cache_association.rb +16 -0
- data/lib/active_scaffold/extensions/localize.rb +10 -0
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +12 -0
- data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +7 -0
- data/lib/active_scaffold/extensions/paginator_extensions.rb +26 -0
- data/lib/active_scaffold/extensions/reverse_associations.rb +64 -0
- data/lib/active_scaffold/extensions/routing_mapper.rb +48 -0
- data/lib/active_scaffold/extensions/to_label.rb +8 -0
- data/lib/active_scaffold/extensions/unsaved_associated.rb +61 -0
- data/lib/active_scaffold/extensions/unsaved_record.rb +20 -0
- data/lib/active_scaffold/extensions/usa_state.rb +46 -0
- data/lib/active_scaffold/finder.rb +399 -0
- data/lib/active_scaffold/helpers/association_helpers.rb +42 -0
- data/lib/active_scaffold/helpers/controller_helpers.rb +94 -0
- data/lib/active_scaffold/helpers/form_column_helpers.rb +322 -0
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +64 -0
- data/lib/active_scaffold/helpers/id_helpers.rb +131 -0
- data/lib/active_scaffold/helpers/list_column_helpers.rb +374 -0
- data/lib/active_scaffold/helpers/pagination_helpers.rb +62 -0
- data/lib/active_scaffold/helpers/search_column_helpers.rb +257 -0
- data/lib/active_scaffold/helpers/show_column_helpers.rb +44 -0
- data/lib/active_scaffold/helpers/view_helpers.rb +398 -0
- data/lib/active_scaffold/marked_model.rb +38 -0
- data/lib/active_scaffold/paginator.rb +136 -0
- data/lib/active_scaffold/responds_to_parent.rb +70 -0
- data/lib/active_scaffold/tableless.rb +83 -0
- data/lib/active_scaffold/version.rb +9 -0
- data/lib/active_scaffold.rb +373 -0
- data/lib/active_scaffold_env.rb +13 -0
- data/lib/generators/active_scaffold/USAGE +29 -0
- data/lib/generators/active_scaffold/active_scaffold_generator.rb +21 -0
- data/lib/generators/active_scaffold_controller/USAGE +19 -0
- data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +29 -0
- data/lib/generators/active_scaffold_controller/templates/controller.rb +4 -0
- data/lib/generators/active_scaffold_controller/templates/helper.rb +2 -0
- data/public/blank.html +33 -0
- data/shoulda_macros/macros.rb +136 -0
- data/vendor/assets/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/vendor/assets/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/vendor/assets/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/vendor/assets/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/vendor/assets/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/vendor/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/vendor/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/vendor/assets/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/vendor/assets/images/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_228ef1_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_ef8c08_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_ffd27a_256x240.png +0 -0
- data/vendor/assets/images/ui-icons_ffffff_256x240.png +0 -0
- data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1276 -0
- data/vendor/assets/stylesheets/jquery-ui.css +568 -0
- metadata +261 -17
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module ActiveScaffold::DataStructures
|
|
2
|
+
class Columns
|
|
3
|
+
include Enumerable
|
|
4
|
+
include ActiveScaffold::Configurable
|
|
5
|
+
|
|
6
|
+
# The motivation for this collection is that this Columns data structure fills two roles: it provides
|
|
7
|
+
# the master list of all known columns, and it provides an inheritable list for all other actions (e.g.
|
|
8
|
+
# Create and Update and List). Well we actually want to *know* about as many columns as possible, so
|
|
9
|
+
# we don't want people actually removing columns from @set. But at the same time, we want to be able to
|
|
10
|
+
# manage which columns get inherited. Tada!
|
|
11
|
+
#
|
|
12
|
+
# This collection is referenced by other parts of ActiveScaffold and by methods within this DataStructure.
|
|
13
|
+
# IT IS NOT MEANT FOR PUBLIC USE (but if you know what you're doing, go ahead)
|
|
14
|
+
def _inheritable=(value)
|
|
15
|
+
@sorted = true
|
|
16
|
+
@_inheritable = value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# This accessor is used by ActionColumns to create new Column objects without adding them to this set
|
|
20
|
+
attr_reader :active_record_class
|
|
21
|
+
|
|
22
|
+
def initialize(active_record_class, *args)
|
|
23
|
+
@active_record_class = active_record_class
|
|
24
|
+
@_inheritable = []
|
|
25
|
+
@set = []
|
|
26
|
+
|
|
27
|
+
self.add *args
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# the way to add columns to the set. this is primarily useful for virtual columns.
|
|
31
|
+
# note that this also makes columns inheritable
|
|
32
|
+
def add(*args)
|
|
33
|
+
args.flatten! # allow [] as a param
|
|
34
|
+
args = args.collect{ |a| a.to_sym }
|
|
35
|
+
|
|
36
|
+
# make the columns inheritable
|
|
37
|
+
@_inheritable.concat(args)
|
|
38
|
+
# then add columns to @set (unless they already exist)
|
|
39
|
+
args.each { |a| @set << ActiveScaffold::DataStructures::Column.new(a.to_sym, @active_record_class) unless find_by_name(a) }
|
|
40
|
+
end
|
|
41
|
+
alias_method :<<, :add
|
|
42
|
+
|
|
43
|
+
def exclude(*args)
|
|
44
|
+
# only remove columns from _inheritable. we never want to completely forget about a column.
|
|
45
|
+
args.each { |a| @_inheritable.delete a }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# returns an array of columns with the provided names
|
|
49
|
+
def find_by_names(*names)
|
|
50
|
+
@set.find_all { |column| names.include? column.name }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# returns the column of the given name.
|
|
54
|
+
def find_by_name(name)
|
|
55
|
+
# this works because of `def column.=='
|
|
56
|
+
column = @set.find { |c| c == name }
|
|
57
|
+
column
|
|
58
|
+
end
|
|
59
|
+
alias_method :[], :find_by_name
|
|
60
|
+
|
|
61
|
+
def each
|
|
62
|
+
@set.each {|i| yield i }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def _inheritable
|
|
66
|
+
if @sorted
|
|
67
|
+
@_inheritable
|
|
68
|
+
else
|
|
69
|
+
@_inheritable.sort do |a, b|
|
|
70
|
+
self[a] <=> self[b]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module ActiveScaffold::DataStructures
|
|
2
|
+
# Wrapper for error strings so that they may be exported using to_xxx
|
|
3
|
+
class ErrorMessage
|
|
4
|
+
def initialize(error)
|
|
5
|
+
@error = error
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def public_attributes
|
|
9
|
+
{ :error => @error }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_xml
|
|
13
|
+
public_attributes.to_xml(:root => "errors")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_yaml
|
|
17
|
+
public_attributes.to_yaml
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_s
|
|
21
|
+
@error
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
module ActiveScaffold::DataStructures
|
|
2
|
+
class NestedInfo
|
|
3
|
+
def self.get(model, params)
|
|
4
|
+
nested_info = {}
|
|
5
|
+
begin
|
|
6
|
+
nested_info[:name] = (params[:association] || params[:named_scope]).to_sym
|
|
7
|
+
nested_info[:parent_scaffold] = "#{params[:parent_scaffold].to_s.camelize}Controller".constantize
|
|
8
|
+
nested_info[:parent_model] = nested_info[:parent_scaffold].active_scaffold_config.model
|
|
9
|
+
nested_info[:parent_id] = if params[:association].nil?
|
|
10
|
+
params[nested_info[:parent_model].name.foreign_key]
|
|
11
|
+
else
|
|
12
|
+
params[nested_info[:parent_model].reflect_on_association(params[:association].to_sym).active_record.name.foreign_key]
|
|
13
|
+
end
|
|
14
|
+
if nested_info[:parent_id]
|
|
15
|
+
unless params[:association].nil?
|
|
16
|
+
ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, nested_info)
|
|
17
|
+
else
|
|
18
|
+
ActiveScaffold::DataStructures::NestedInfoScope.new(model, nested_info)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
rescue ActiveScaffold::ControllerNotFound
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :constrained_fields, :scope
|
|
27
|
+
|
|
28
|
+
def initialize(model, nested_info)
|
|
29
|
+
@parent_model = nested_info[:parent_model]
|
|
30
|
+
@parent_id = nested_info[:parent_id]
|
|
31
|
+
@parent_scaffold = nested_info[:parent_scaffold]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_params
|
|
35
|
+
{:parent_scaffold => parent_scaffold.controller_path}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def new_instance?
|
|
39
|
+
result = @new_instance.nil?
|
|
40
|
+
@new_instance = false
|
|
41
|
+
result
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def parent_scope
|
|
45
|
+
@parent_scope ||= parent_model.find(parent_id)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def habtm?
|
|
49
|
+
false
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def has_many?
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def belongs_to?
|
|
57
|
+
false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def has_one?
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def singular_association?
|
|
65
|
+
belongs_to? || has_one?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def plural_association?
|
|
69
|
+
has_many? || habtm?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def through_association?
|
|
73
|
+
false
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def readonly?
|
|
77
|
+
false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def sorted?
|
|
81
|
+
false
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class NestedInfoAssociation < NestedInfo
|
|
86
|
+
def initialize(model, nested_info)
|
|
87
|
+
super(model, nested_info)
|
|
88
|
+
@association = parent_model.reflect_on_association(nested_info[:name])
|
|
89
|
+
iterate_model_associations(model)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def name
|
|
93
|
+
self.association.name
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def has_many?
|
|
97
|
+
association.macro == :has_many
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def habtm?
|
|
101
|
+
association.macro == :has_and_belongs_to_many
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def belongs_to?
|
|
105
|
+
association.belongs_to?
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def has_one?
|
|
109
|
+
association.macro == :has_one
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def through_association?
|
|
113
|
+
association.options[:through]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def readonly?
|
|
117
|
+
association.options[:readonly]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def sorted?
|
|
121
|
+
association.options.has_key? :order
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def default_sorting
|
|
125
|
+
association.options[:order]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def to_params
|
|
129
|
+
super.merge(:association => @association.name, :assoc_id => parent_id)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
protected
|
|
133
|
+
|
|
134
|
+
def iterate_model_associations(model)
|
|
135
|
+
@constrained_fields = Set.new
|
|
136
|
+
constrained_fields << association.foreign_key.to_sym unless association.belongs_to?
|
|
137
|
+
model.reflect_on_all_associations.each do |current|
|
|
138
|
+
if !current.belongs_to? && association != current && association.foreign_key.to_s == current.association_foreign_key.to_s
|
|
139
|
+
constrained_fields << current.name.to_sym
|
|
140
|
+
@child_association = current if current.klass == @parent_model
|
|
141
|
+
end
|
|
142
|
+
if association.foreign_key.to_s == current.foreign_key.to_s
|
|
143
|
+
# show columns for has_many and has_one child associationes
|
|
144
|
+
constrained_fields << current.name.to_sym if current.belongs_to?
|
|
145
|
+
if association.options[:as] and current.options[:polymorphic]
|
|
146
|
+
@child_association = current if association.options[:as].to_sym == current.name
|
|
147
|
+
else
|
|
148
|
+
@child_association = current if current.klass == @parent_model
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
@constrained_fields = @constrained_fields.to_a
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class NestedInfoScope < NestedInfo
|
|
157
|
+
def initialize(model, nested_info)
|
|
158
|
+
super(model, nested_info)
|
|
159
|
+
@scope = nested_info[:name]
|
|
160
|
+
@constrained_fields = []
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def to_params
|
|
164
|
+
super.merge(:named_scope => @scope)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def name
|
|
168
|
+
self.scope
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module ActiveScaffold::DataStructures
|
|
2
|
+
class Set
|
|
3
|
+
include Enumerable
|
|
4
|
+
include ActiveScaffold::Configurable
|
|
5
|
+
|
|
6
|
+
def initialize(*args)
|
|
7
|
+
set_values(*args)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def set_values(*args)
|
|
11
|
+
@set = []
|
|
12
|
+
self.add *args
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# the way to add items to the set.
|
|
16
|
+
def add(*args)
|
|
17
|
+
args.flatten! # allow [] as a param
|
|
18
|
+
args.each { |arg|
|
|
19
|
+
arg = arg.to_sym if arg.is_a? String
|
|
20
|
+
@set << arg unless @set.include? arg # avoid duplicates
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
alias_method :<<, :add
|
|
24
|
+
|
|
25
|
+
# the way to remove items from the set.
|
|
26
|
+
def exclude(*args)
|
|
27
|
+
args.flatten! # allow [] as a param
|
|
28
|
+
args.collect! { |a| a.to_sym } # symbolize the args
|
|
29
|
+
# check respond_to? :to_sym, ActionColumns doesn't respond to to_sym
|
|
30
|
+
@set.reject! { |c| c.respond_to? :to_sym and args.include? c.to_sym } # reject all items specified
|
|
31
|
+
end
|
|
32
|
+
alias_method :remove, :exclude
|
|
33
|
+
|
|
34
|
+
# returns an array of items with the provided names
|
|
35
|
+
def find_by_names(*names)
|
|
36
|
+
@set.find_all { |item| names.include? item }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# returns the item of the given name.
|
|
40
|
+
def find_by_name(name)
|
|
41
|
+
# this works because of `def item.=='
|
|
42
|
+
item = @set.find { |c| c == name }
|
|
43
|
+
item
|
|
44
|
+
end
|
|
45
|
+
alias_method :[], :find_by_name
|
|
46
|
+
|
|
47
|
+
def each
|
|
48
|
+
@set.each {|i| yield i }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# returns the number of items in the set
|
|
52
|
+
def length
|
|
53
|
+
@set.length
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def empty?
|
|
57
|
+
@set.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
module ActiveScaffold::DataStructures
|
|
2
|
+
# encapsulates the column sorting configuration for the List view
|
|
3
|
+
class Sorting
|
|
4
|
+
include Enumerable
|
|
5
|
+
|
|
6
|
+
def initialize(columns)
|
|
7
|
+
@columns = columns
|
|
8
|
+
@clauses = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def set_default_sorting(model)
|
|
12
|
+
model_scope = model.send(:build_default_scope)
|
|
13
|
+
order_clause = model_scope.arel.order_clauses.join(",") if model_scope
|
|
14
|
+
|
|
15
|
+
# If an ORDER BY clause is found set default sorting according to it, else
|
|
16
|
+
# fallback to setting primary key ordering
|
|
17
|
+
if order_clause
|
|
18
|
+
set_sorting_from_order_clause(order_clause, model.table_name)
|
|
19
|
+
@default_sorting = true
|
|
20
|
+
else
|
|
21
|
+
set(model.primary_key, 'ASC') if model.column_names.include?(model.primary_key)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def set_nested_sorting(table_name, order_clause)
|
|
26
|
+
clear
|
|
27
|
+
set_sorting_from_order_clause(order_clause, table_name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# add a clause to the sorting, assuming the column is sortable
|
|
31
|
+
def add(column_name, direction = nil)
|
|
32
|
+
direction ||= 'ASC'
|
|
33
|
+
direction = direction.to_s.upcase
|
|
34
|
+
column = get_column(column_name)
|
|
35
|
+
raise ArgumentError, "Sorting direction unknown" unless [:ASC, :DESC].include? direction.to_sym
|
|
36
|
+
@clauses << [column, direction.untaint] if column and column.sortable?
|
|
37
|
+
raise ArgumentError, "Can't mix :method- and :sql-based sorting" if mixed_sorting?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# an alias for +add+. must accept its arguments in a slightly different form, though.
|
|
41
|
+
def <<(arg)
|
|
42
|
+
add(*arg)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# clears the sorting before setting to the given column/direction
|
|
46
|
+
def set(*args)
|
|
47
|
+
clear
|
|
48
|
+
add(*args)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# clears the sorting
|
|
52
|
+
def clear
|
|
53
|
+
@default_sorting = false
|
|
54
|
+
@clauses = []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# checks whether the given column (a Column object or a column name) is in the sorting
|
|
58
|
+
def sorts_on?(column)
|
|
59
|
+
!get_clause(column).nil?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def direction_of(column)
|
|
63
|
+
clause = get_clause(column)
|
|
64
|
+
return if clause.nil?
|
|
65
|
+
clause[1]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# checks whether any column is configured to sort by method (using a proc)
|
|
69
|
+
def sorts_by_method?
|
|
70
|
+
@clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :method }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def sorts_by_sql?
|
|
74
|
+
@clauses.any? { |sorting| sorting[0].sort.is_a? Hash and sorting[0].sort.has_key? :sql }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# iterate over the clauses
|
|
78
|
+
def each
|
|
79
|
+
@clauses.each { |clause| yield clause }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# provides quick access to the first (and sometimes only) clause
|
|
83
|
+
def first
|
|
84
|
+
@clauses.first
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# builds an order-by clause
|
|
88
|
+
def clause
|
|
89
|
+
return nil if sorts_by_method? || default_sorting?
|
|
90
|
+
|
|
91
|
+
# unless the sorting is by method, create the sql string
|
|
92
|
+
order = []
|
|
93
|
+
each do |sort_column, sort_direction|
|
|
94
|
+
sql = sort_column.sort[:sql]
|
|
95
|
+
next if sql.nil? or sql.empty?
|
|
96
|
+
|
|
97
|
+
order << Array(sql).map {|column| "#{column} #{sort_direction}"}.join(', ')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
order unless order.empty?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
protected
|
|
104
|
+
|
|
105
|
+
# retrieves the sorting clause for the given column
|
|
106
|
+
def get_clause(column)
|
|
107
|
+
column = get_column(column)
|
|
108
|
+
@clauses.find{ |clause| clause[0] == column}
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# possibly converts the given argument into a column object from @columns (if it's not already)
|
|
112
|
+
def get_column(name_or_column)
|
|
113
|
+
# it's a column
|
|
114
|
+
return name_or_column if name_or_column.is_a? ActiveScaffold::DataStructures::Column
|
|
115
|
+
# it's a name
|
|
116
|
+
name_or_column = name_or_column.to_s.split('.').last if name_or_column.to_s.include? '.'
|
|
117
|
+
return @columns[name_or_column]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def mixed_sorting?
|
|
121
|
+
sorts_by_method? and sorts_by_sql?
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def default_sorting?
|
|
125
|
+
@default_sorting
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def set_sorting_from_order_clause(order_clause, model_table_name = nil)
|
|
129
|
+
clear
|
|
130
|
+
order_clause.to_s.split(',').each do |criterion|
|
|
131
|
+
unless criterion.blank?
|
|
132
|
+
order_parts = extract_order_parts(criterion)
|
|
133
|
+
add(order_parts[:column_name], order_parts[:direction]) unless different_table?(model_table_name, order_parts[:table_name])
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def extract_order_parts(criterion_parts)
|
|
139
|
+
column_name_part, direction_part = criterion_parts.strip.split(' ')
|
|
140
|
+
column_name_parts = column_name_part.split('.')
|
|
141
|
+
order = {:direction => extract_direction(direction_part),
|
|
142
|
+
:column_name => remove_quotes(column_name_parts.last)}
|
|
143
|
+
order[:table_name] = remove_quotes(column_name_parts[-2]) if column_name_parts.length >= 2
|
|
144
|
+
order
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def different_table?(model_table_name, order_table_name)
|
|
148
|
+
!order_table_name.nil? && model_table_name != order_table_name
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def remove_quotes(sql_name)
|
|
152
|
+
if sql_name.starts_with?('"') || sql_name.starts_with?('`')
|
|
153
|
+
sql_name[1, (sql_name.length - 2)]
|
|
154
|
+
else
|
|
155
|
+
sql_name
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def extract_direction(direction_part)
|
|
160
|
+
if direction_part.to_s.upcase == 'DESC'
|
|
161
|
+
'DESC'
|
|
162
|
+
else
|
|
163
|
+
'ASC'
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# wrap the action rendering for ActiveScaffold controllers
|
|
2
|
+
module ActionController #:nodoc:
|
|
3
|
+
class Base
|
|
4
|
+
def render_with_active_scaffold(*args, &block)
|
|
5
|
+
if self.class.uses_active_scaffold? and params[:adapter] and @rendering_adapter.nil? and request.xhr?
|
|
6
|
+
@rendering_adapter = true # recursion control
|
|
7
|
+
# if we need an adapter, then we render the actual stuff to a string and insert it into the adapter template
|
|
8
|
+
opts = args.blank? ? Hash.new : args.first
|
|
9
|
+
render :partial => params[:adapter][1..-1],
|
|
10
|
+
:locals => {:payload => render_to_string(opts.merge(:layout => false), &block).html_safe},
|
|
11
|
+
:use_full_path => true, :layout => false, :content_type => :html
|
|
12
|
+
@rendering_adapter = nil # recursion control
|
|
13
|
+
else
|
|
14
|
+
render_without_active_scaffold(*args, &block)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
alias_method_chain :render, :active_scaffold
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
class LookupContext
|
|
3
|
+
module ViewPaths
|
|
4
|
+
def find_all_templates(name, partial = false, locals = {})
|
|
5
|
+
prefixes.collect do |prefix|
|
|
6
|
+
view_paths.collect do |resolver|
|
|
7
|
+
if Rails.version < '3.2.0' # FIXME: remove when rails 3.1 support is dropped
|
|
8
|
+
temp_args = *args_for_lookup(name, [prefix], partial, locals)
|
|
9
|
+
else
|
|
10
|
+
temp_args = *args_for_lookup(name, [prefix], partial, locals, {})
|
|
11
|
+
end
|
|
12
|
+
temp_args[1] = temp_args[1][0]
|
|
13
|
+
resolver.find_all(*temp_args)
|
|
14
|
+
end
|
|
15
|
+
end.flatten!
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# wrap the action rendering for ActiveScaffold views
|
|
22
|
+
module ActionView::Helpers #:nodoc:
|
|
23
|
+
module RenderingHelper
|
|
24
|
+
#
|
|
25
|
+
# Adds two rendering options.
|
|
26
|
+
#
|
|
27
|
+
# ==render :super
|
|
28
|
+
#
|
|
29
|
+
# This syntax skips all template overrides and goes directly to the provided ActiveScaffold templates.
|
|
30
|
+
# Useful if you want to wrap an existing template. Just call super!
|
|
31
|
+
#
|
|
32
|
+
# ==render :active_scaffold => #{controller.to_s}, options = {}+
|
|
33
|
+
#
|
|
34
|
+
# Lets you embed an ActiveScaffold by referencing the controller where it's configured.
|
|
35
|
+
#
|
|
36
|
+
# You may specify options[:constraints] for the embedded scaffold. These constraints have three effects:
|
|
37
|
+
# * the scaffold's only displays records matching the constraint
|
|
38
|
+
# * all new records created will be assigned the constrained values
|
|
39
|
+
# * constrained columns will be hidden (they're pretty boring at this point)
|
|
40
|
+
#
|
|
41
|
+
# You may also specify options[:conditions] for the embedded scaffold. These only do 1/3 of what
|
|
42
|
+
# constraints do (they only limit search results). Any format accepted by ActiveRecord::Base.find is valid.
|
|
43
|
+
#
|
|
44
|
+
# Defining options[:label] lets you completely customize the list title for the embedded scaffold.
|
|
45
|
+
#
|
|
46
|
+
def render_with_active_scaffold(*args, &block)
|
|
47
|
+
if args.first == :super
|
|
48
|
+
last_view = view_stack.last || {:view => instance_variable_get(:@virtual_path).split('/').last}
|
|
49
|
+
options = args[1] || {}
|
|
50
|
+
options[:locals] ||= {}
|
|
51
|
+
options[:locals].reverse_merge!(last_view[:locals] || {})
|
|
52
|
+
if last_view[:templates].nil?
|
|
53
|
+
last_view[:templates] = lookup_context.find_all_templates(last_view[:view], last_view[:partial], options[:locals].keys)
|
|
54
|
+
last_view[:templates].shift
|
|
55
|
+
end
|
|
56
|
+
options[:template] = last_view[:templates].shift
|
|
57
|
+
view_stack << last_view
|
|
58
|
+
result = render_without_active_scaffold options
|
|
59
|
+
view_stack.pop
|
|
60
|
+
result
|
|
61
|
+
elsif args.first.is_a? Hash and args.first[:active_scaffold]
|
|
62
|
+
require 'digest/md5'
|
|
63
|
+
options = args.first
|
|
64
|
+
|
|
65
|
+
remote_controller = options[:active_scaffold]
|
|
66
|
+
constraints = options[:constraints]
|
|
67
|
+
conditions = options[:conditions]
|
|
68
|
+
eid = Digest::MD5.hexdigest(params[:controller] + remote_controller.to_s + constraints.to_s + conditions.to_s)
|
|
69
|
+
session["as:#{eid}"] = {:constraints => constraints, :conditions => conditions, :list => {:label => args.first[:label]}}
|
|
70
|
+
options[:params] ||= {}
|
|
71
|
+
options[:params].merge! :eid => eid, :embedded => true
|
|
72
|
+
|
|
73
|
+
id = "as_#{eid}-embedded"
|
|
74
|
+
url_options = {:controller => remote_controller.to_s, :action => 'index'}.merge(options[:params])
|
|
75
|
+
|
|
76
|
+
if controller.respond_to?(:render_component_into_view)
|
|
77
|
+
controller.send(:render_component_into_view, url_options)
|
|
78
|
+
else
|
|
79
|
+
content_tag(:div, :id => id, :class => 'active-scaffold-component') do
|
|
80
|
+
url = url_for(url_options)
|
|
81
|
+
# parse the ActiveRecord model name from the controller path, which
|
|
82
|
+
# might be a namespaced controller (e.g., 'admin/admins')
|
|
83
|
+
model = remote_controller.to_s.sub(/.*\//, '').singularize
|
|
84
|
+
content_tag(:div, :class => 'active-scaffold-header') do
|
|
85
|
+
content_tag :h2, link_to(args.first[:label] || active_scaffold_config_for(model).list.label, url, :remote => true)
|
|
86
|
+
end <<
|
|
87
|
+
if ActiveScaffold.js_framework == :prototype
|
|
88
|
+
javascript_tag("new Ajax.Updater('#{id}', '#{url}', {method: 'get', evalScripts: true});")
|
|
89
|
+
elsif ActiveScaffold.js_framework == :jquery
|
|
90
|
+
javascript_tag("jQuery('##{id}').load('#{url}');")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
else
|
|
96
|
+
options = args.first
|
|
97
|
+
if options.is_a?(Hash)
|
|
98
|
+
current_view = {:view => options[:partial], :partial => true} if options[:partial]
|
|
99
|
+
current_view = {:view => options[:template], :partial => false} if current_view.nil? && options[:template]
|
|
100
|
+
current_view[:locals] = options[:locals] if !current_view.nil? && options[:locals]
|
|
101
|
+
view_stack << current_view if current_view.present?
|
|
102
|
+
end
|
|
103
|
+
result = render_without_active_scaffold(*args, &block)
|
|
104
|
+
view_stack.pop if current_view.present?
|
|
105
|
+
result
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
alias_method_chain :render, :active_scaffold
|
|
109
|
+
|
|
110
|
+
def view_stack
|
|
111
|
+
@_view_stack ||= []
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Bugfix: Team.offset(1).limit(1) throws an error
|
|
2
|
+
ActiveRecord::Base.instance_eval do
|
|
3
|
+
def offset(*args, &block)
|
|
4
|
+
scoped.__send__(:offset, *args, &block)
|
|
5
|
+
rescue NoMethodError
|
|
6
|
+
if scoped.nil?
|
|
7
|
+
'depends on :allow_nil'
|
|
8
|
+
else
|
|
9
|
+
raise
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Relation
|
|
3
|
+
def target=(records)
|
|
4
|
+
@loaded = true
|
|
5
|
+
@records = records
|
|
6
|
+
@records
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
module ActiveRecord
|
|
11
|
+
module Associations
|
|
12
|
+
class CollectionProxy
|
|
13
|
+
delegate :target=, :to => :@association
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|