puffer 0.0.32 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +1 -26
- data/Gemfile.lock +66 -64
- data/README.md +34 -23
- data/Rakefile +1 -11
- data/VERSION +1 -1
- data/app/assets/javascripts/puffer/application.js +6 -1
- data/app/assets/javascripts/puffer/associations.js +18 -0
- data/app/assets/javascripts/puffer/puffer.js +7 -0
- data/app/assets/javascripts/puffer/right-calendar-src.js +19 -3
- data/app/assets/javascripts/puffer/right-dnd-src.js +591 -0
- data/app/assets/javascripts/puffer/right-in-edit-src.js +373 -0
- data/app/assets/javascripts/puffer/right-keys-src.js +87 -0
- data/app/assets/javascripts/puffer/{paginator.js → right-paginator-src.js} +0 -0
- data/app/assets/javascripts/puffer/right-slider-src.js +29 -32
- data/app/assets/javascripts/puffer/right-sortable-src.js +430 -0
- data/app/assets/javascripts/puffer/right-src.js +358 -99
- data/app/assets/stylesheets/puffer/puffer.css +29 -4
- data/app/components/base/form.html.erb +8 -14
- data/app/components/base_component.rb +1 -1
- data/app/components/boolean/form.html.erb +5 -3
- data/app/components/boolean/index.html.erb +6 -2
- data/app/components/boolean_component.rb +2 -2
- data/app/components/date_time/filter.html.erb +9 -0
- data/app/components/date_time/form.html.erb +8 -4
- data/app/components/date_time_component.rb +21 -5
- data/app/components/file/form.html.erb +8 -4
- data/app/components/hidden/form.html.erb +3 -1
- data/app/components/nested_attributes_many/form.html.erb +47 -0
- data/app/components/nested_attributes_many_component.rb +7 -0
- data/app/components/nested_attributes_one/form.html.erb +48 -0
- data/app/components/nested_attributes_one_component.rb +7 -0
- data/app/components/password/form.html.erb +8 -4
- data/app/components/password_component.rb +1 -1
- data/app/components/references_many/index.html.erb +1 -1
- data/app/components/references_one/choose.html.erb +1 -1
- data/app/components/references_one/form.html.erb +10 -9
- data/app/components/references_one_component.rb +0 -1
- data/app/components/render_component.rb +13 -0
- data/app/components/select/filter.html.erb +4 -2
- data/app/components/select/form.html.erb +8 -4
- data/app/components/text/form.html.erb +8 -4
- data/app/controllers/admin/sessions_controller.rb +1 -21
- data/app/controllers/puffer/base.rb +10 -3
- data/app/controllers/puffer/dashboard_base.rb +7 -1
- data/app/controllers/puffer/{sessions_base.rb → sessions/base.rb} +10 -7
- data/app/controllers/puffer/sessions/clearance.rb +29 -0
- data/app/controllers/puffer/{sessions_devise_base.rb → sessions/devise.rb} +1 -1
- data/app/controllers/puffer/sessions/simple.rb +28 -0
- data/app/controllers/puffer/tree_base.rb +1 -1
- data/app/models/puffer_user.rb +3 -0
- data/app/views/layouts/puffer.html.erb +3 -3
- data/app/views/puffer/base/_edit.html.erb +15 -0
- data/app/views/puffer/base/_index.html.erb +26 -0
- data/app/views/puffer/base/_show.html.erb +13 -0
- data/app/views/puffer/base/_table.html.erb +1 -1
- data/app/views/puffer/base/edit.html.erb +1 -15
- data/app/views/puffer/base/edit.js.erb +1 -0
- data/app/views/puffer/base/index.html.erb +1 -20
- data/app/views/puffer/base/index.js.erb +1 -0
- data/app/views/puffer/base/new.html.erb +1 -1
- data/app/views/puffer/base/show.html.erb +1 -22
- data/app/views/puffer/base/show.js.erb +1 -0
- data/app/views/puffer/base/update.js.erb +1 -0
- data/app/views/puffer/sessions/base/new.html.erb +11 -0
- data/app/views/puffer/tree_base/_record.html.erb +1 -1
- data/lib/puffer/component.rb +14 -47
- data/lib/puffer/controller/auth.rb +13 -9
- data/lib/puffer/controller/config.rb +18 -0
- data/lib/puffer/controller/mutate.rb +8 -8
- data/lib/puffer/engine.rb +5 -0
- data/lib/puffer/field.rb +5 -11
- data/lib/puffer/filters.rb +86 -56
- data/lib/puffer/helpers/component_helper.rb +24 -0
- data/lib/puffer/helpers/puffer_helper.rb +65 -0
- data/lib/puffer/helpers/puffer_tree_helper.rb +19 -0
- data/lib/puffer/orm_adapter/active_record.rb +40 -11
- data/lib/puffer/orm_adapter/base.rb +9 -0
- data/lib/puffer/orm_adapter/mongoid.rb +32 -9
- data/lib/puffer/resource/node.rb +2 -2
- data/lib/puffer/resource/routing.rb +30 -16
- data/lib/puffer/resource.rb +20 -20
- data/lib/puffer/version.rb +3 -0
- data/lib/puffer.rb +26 -5
- data/puffer.gemspec +34 -296
- data/spec/app/components/base_component_spec.rb +1 -1
- data/spec/app/components/boolean_component_spec.rb +2 -0
- data/spec/app/components/date_time_component_spec.rb +1 -0
- data/spec/app/components/file_component_spec.rb +1 -0
- data/spec/app/components/hidden_component_spec.rb +1 -0
- data/spec/app/components/password_component_spec.rb +2 -0
- data/spec/app/components/select_component_spec.rb +1 -0
- data/spec/app/components/string_component_spec.rb +1 -0
- data/spec/app/components/text_component_spec.rb +1 -0
- data/spec/dummy/app/controllers/admin/news_controller.rb +2 -0
- data/spec/dummy/app/controllers/admin/profiles_controller.rb +1 -1
- data/spec/dummy/app/controllers/admin/users_controller.rb +2 -0
- data/spec/dummy/app/controllers/orms/active_record_orm_primals_controller.rb +8 -0
- data/spec/dummy/app/helpers/news_helper.rb +7 -0
- data/spec/dummy/app/models/active_record_orm/has_many_reference.rb +5 -0
- data/spec/dummy/app/models/active_record_orm/has_one_reference.rb +5 -0
- data/spec/dummy/app/models/active_record_orm/primal.rb +4 -0
- data/spec/dummy/config/environments/development.rb +1 -1
- data/spec/dummy/db/migrate/20111120144025_create_active_record_orm_has_one_references.rb +10 -0
- data/spec/dummy/db/migrate/20111122203304_create_active_record_orm_has_many_references.rb +10 -0
- data/spec/dummy/db/schema.rb +15 -1
- data/spec/helpers/puffer_helper_spec.rb +1 -1
- data/spec/lib/fields_spec.rb +0 -9
- data/spec/lib/filters_spec.rb +4 -8
- data/spec/lib/orm_adapter/base_shared.rb +22 -0
- data/spec/spec_helper.rb +1 -1
- metadata +89 -60
- data/app/components/string/form.html.erb +0 -5
- data/app/helpers/puffer_helper.rb +0 -51
- data/app/helpers/puffer_tree_helper.rb +0 -15
- data/app/views/puffer/sessions_base/new.html.erb +0 -11
- data/lib/puffer/extensions/form.rb +0 -16
data/lib/puffer/filters.rb
CHANGED
@@ -1,40 +1,103 @@
|
|
1
1
|
module Puffer
|
2
2
|
class Filters
|
3
|
+
class Diapason < Struct.new(:from, :till)
|
4
|
+
def empty?
|
5
|
+
from.blank? && till.blank?
|
6
|
+
end
|
7
|
+
|
8
|
+
def persisted?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_query(key)
|
13
|
+
{:from => from, :till => till}.to_query(key)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
include ActiveModel::Conversion
|
4
18
|
extend ActiveModel::Naming
|
5
19
|
extend ActiveModel::Translation
|
6
20
|
include ActiveModel::AttributeMethods
|
7
21
|
|
8
|
-
delegate :model_name, :to => 'self.class'
|
22
|
+
delegate :model_name, :special_attributes, :to => 'self.class'
|
9
23
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
24
|
+
def self.special_attributes
|
25
|
+
%w(puffer_search puffer_order)
|
26
|
+
end
|
27
|
+
|
28
|
+
special_attributes.each do |attribute|
|
29
|
+
define_method attribute do
|
30
|
+
read_attribute attribute
|
31
|
+
end
|
32
|
+
define_method "#{attribute}=" do |value|
|
33
|
+
write_attribute attribute, value
|
14
34
|
end
|
15
35
|
end
|
16
36
|
|
37
|
+
attr_reader :fieldset
|
38
|
+
|
39
|
+
def initialize fieldset, attributes = {}
|
40
|
+
@attributes = {}
|
41
|
+
@fieldset = fieldset
|
42
|
+
generate_attribute_methods
|
43
|
+
|
44
|
+
self.attributes = attributes
|
45
|
+
end
|
46
|
+
|
17
47
|
def read_attribute name
|
18
|
-
attributes[name]
|
48
|
+
@attributes[name.to_s]
|
19
49
|
end
|
20
50
|
|
21
51
|
def write_attribute name, value
|
22
|
-
|
52
|
+
if value.is_a? Hash
|
53
|
+
value.each do |key, subvalue|
|
54
|
+
@attributes[name.to_s][key] = subvalue if subvalue.present?
|
55
|
+
end
|
56
|
+
else
|
57
|
+
@attributes[name.to_s] = value
|
58
|
+
end if value.present?
|
23
59
|
end
|
24
60
|
|
25
|
-
def
|
26
|
-
|
61
|
+
def any?
|
62
|
+
attributes.values.any?
|
27
63
|
end
|
28
64
|
|
29
|
-
def
|
30
|
-
|
65
|
+
def attributes
|
66
|
+
(fieldset.map(&:field_name) + special_attributes).reduce(ActiveSupport::HashWithIndifferentAccess.new()) do |res, attribute|
|
67
|
+
res.merge attribute => send(attribute)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def attributes= attributes = {}
|
72
|
+
attributes.each do |(key, value)|
|
73
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def generate_attribute_methods
|
78
|
+
fieldset.each do |field|
|
79
|
+
define_singleton_method :"#{field}" do
|
80
|
+
read_attribute field
|
81
|
+
end
|
82
|
+
define_singleton_method :"#{field}=" do |value|
|
83
|
+
write_attribute field, value
|
84
|
+
end
|
85
|
+
|
86
|
+
if %(date, time, datetime, date_time, timestamp).include?(field.type.to_s)
|
87
|
+
@attributes[field.to_s] = Puffer::Filters::Diapason.new
|
88
|
+
|
89
|
+
define_singleton_method :"#{field}_attributes=" do |value|
|
90
|
+
write_attribute field, value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
31
94
|
end
|
32
95
|
|
33
96
|
def conditions
|
34
|
-
|
97
|
+
fieldset.map(&:field_name).reduce(ActiveSupport::HashWithIndifferentAccess.new()) do |res, attribute|
|
35
98
|
value = send(attribute)
|
36
99
|
|
37
|
-
unless value.
|
100
|
+
unless value.blank?
|
38
101
|
value = case value
|
39
102
|
when 'puffer_nil' then nil
|
40
103
|
when 'puffer_blank' then ''
|
@@ -52,54 +115,21 @@ module Puffer
|
|
52
115
|
end
|
53
116
|
|
54
117
|
def order
|
55
|
-
puffer_order
|
118
|
+
puffer_order.to_s.split(' ').map(&:to_sym)
|
56
119
|
end
|
57
120
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def controller_filters controller
|
68
|
-
scope = "#{controller}Filters".split('::')[0..-2].join('::').constantize rescue Kernel
|
69
|
-
name = "#{controller}Filters".demodulize
|
70
|
-
|
71
|
-
if scope.const_defined?(name)
|
72
|
-
scope.const_get(name)
|
73
|
-
else
|
74
|
-
attributes_from_controller = controller.index_fields.reduce({}) do |res, field|
|
75
|
-
res[field.field_name] = nil
|
76
|
-
res
|
77
|
-
end
|
78
|
-
|
79
|
-
attributes_from_controller.merge!('puffer_search' => nil, 'puffer_order' => nil)
|
80
|
-
|
81
|
-
klass = Class.new(self)
|
82
|
-
|
83
|
-
attributes_from_controller.keys.each do |name|
|
84
|
-
klass.send :define_method, name do
|
85
|
-
read_attribute name
|
86
|
-
end
|
87
|
-
klass.send :define_method, "#{name}=" do |value|
|
88
|
-
write_attribute name, value
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
klass.send :define_method, :attributes do
|
93
|
-
attributes_from_controller
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
|
-
scope.const_set(name, klass)
|
98
|
-
end
|
121
|
+
def query
|
122
|
+
(fieldset.map(&:field_name) + special_attributes).reduce(ActiveSupport::HashWithIndifferentAccess.new()) do |res, attribute|
|
123
|
+
value = send(attribute)
|
124
|
+
attribute = "#{attribute}_attributes" if respond_to?("#{attribute}_attributes=")
|
125
|
+
res[attribute] = value if value.present?
|
126
|
+
res
|
99
127
|
end
|
100
128
|
end
|
101
129
|
|
102
|
-
|
130
|
+
def persisted?
|
131
|
+
false
|
132
|
+
end
|
103
133
|
|
104
134
|
end
|
105
135
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Puffer
|
2
|
+
module Helpers
|
3
|
+
module ComponentHelper
|
4
|
+
|
5
|
+
def component_wrap name = :span, options = {}, &block
|
6
|
+
content_tag name, options.merge(:id => component_id), &block
|
7
|
+
end
|
8
|
+
|
9
|
+
def paginate(scope, options = {}, &block)
|
10
|
+
paginator = Kaminari::Helpers::Paginator.new parent_controller.view_context, options.reverse_merge(:current_page => scope.current_page, :num_pages => scope.num_pages, :per_page => scope.limit_value, :param_name => Kaminari.config.param_name, :remote => false)
|
11
|
+
paginator.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def component_fields_for record, &block
|
15
|
+
if opts[:builder]
|
16
|
+
capture opts[:builder], &block
|
17
|
+
else
|
18
|
+
fields_for record, &block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Puffer
|
4
|
+
module Helpers
|
5
|
+
module PufferHelper
|
6
|
+
|
7
|
+
def puffer_scopes_navigation
|
8
|
+
Rails.application.routes.resources_tree.map(&:scope).uniq.each do |scope|
|
9
|
+
yield scope, send("#{scope}_root_path"), scope == puffer_namespace
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def puffer_groups_navigation namespace = puffer_namespace
|
14
|
+
Rails.application.routes.resources_tree.roots.select {|node| node.scope == namespace}.uniq_by(&:group).each do |resource_node|
|
15
|
+
if resource_node.group
|
16
|
+
path = send("#{resource_node.scope}_#{resource_node.url_segment}_path")
|
17
|
+
current = resource.resource_node ? resource.root.resource_node.group == resource_node.group : false
|
18
|
+
|
19
|
+
yield resource_node.group, path, current
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def puffer_resources_navigation namespace = puffer_namespace, group = configuration.group
|
25
|
+
Rails.application.routes.resources_tree.roots.select {|node| node.scope == namespace && node.group == group}.each do |resource_node|
|
26
|
+
title = resource_node.controller.model.model_name.human
|
27
|
+
path = send("#{resource_node.scope}_#{resource_node.url_segment}_path")
|
28
|
+
current = resource.resource_node ? resource.root.resource_node == resource_node : false
|
29
|
+
|
30
|
+
yield title, path, current
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def render_head field
|
35
|
+
head = []
|
36
|
+
if field.column
|
37
|
+
head.push link_to_unless(puffer_filters.puffer_order == field.to_s, "▼", resource.collection_path(:page => params[:page], Puffer::Filters.model_name.param_key => puffer_filters.query.merge(:puffer_order => field)))
|
38
|
+
head.push link_to_unless(puffer_filters.puffer_order == [field, :desc].join(' '), "▲", resource.collection_path(:page => params[:page], Puffer::Filters.model_name.param_key => puffer_filters.query.merge(:puffer_order => [field, :desc].join(' '))))
|
39
|
+
end
|
40
|
+
head.push field.human
|
41
|
+
head.join(' ').html_safe
|
42
|
+
end
|
43
|
+
|
44
|
+
def render_field field, record
|
45
|
+
if field.options[:render]
|
46
|
+
case field.options[:render]
|
47
|
+
when Symbol then
|
48
|
+
res = send(field.options[:render], record)
|
49
|
+
when Proc then
|
50
|
+
res = field.options[:render].bind(self).call(record)
|
51
|
+
else ''
|
52
|
+
end
|
53
|
+
else
|
54
|
+
res = record.call_chain(field.to_s)
|
55
|
+
end
|
56
|
+
unless field.native?
|
57
|
+
url = edit_polymorphic_path [resource.scope, record.call_chain(field.path)] rescue nil
|
58
|
+
res = link_to res, url if url
|
59
|
+
end
|
60
|
+
res
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Puffer
|
2
|
+
module Helpers
|
3
|
+
module PufferTreeHelper
|
4
|
+
|
5
|
+
def puffer_tree hash, options = {}, &block
|
6
|
+
content_tag :ul, options do
|
7
|
+
puffer_tree_node hash, &block
|
8
|
+
end if hash.present?
|
9
|
+
end
|
10
|
+
|
11
|
+
def puffer_tree_node hash, &block
|
12
|
+
hash.keys.each do |node|
|
13
|
+
block.call node, render_tree(hash[node], &block)
|
14
|
+
end if hash.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -8,23 +8,40 @@ module Puffer
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def reflection name
|
12
|
+
reflection = klass.reflect_on_association(name.to_sym)
|
13
|
+
Reflection.new(
|
14
|
+
:klass => reflection.klass,
|
15
|
+
:macro => reflection.macro,
|
16
|
+
:through? => !!reflection.through_reflection
|
17
|
+
) if reflection
|
18
|
+
end
|
19
|
+
|
11
20
|
def filter scope, fields, options = {}
|
12
|
-
fields = fields.columns
|
13
21
|
conditions, order = extract_conditions_and_order!(options)
|
14
22
|
|
15
|
-
|
16
|
-
|
17
|
-
|
23
|
+
order = order.map { |name, dir| field = fields[name]; "#{query_order(field)} #{dir}" if field && field.column }.compact.join(', ')
|
24
|
+
|
25
|
+
conditions_fields = fields.select {|f| f.column && conditions.keys.include?(f.field_name)}.to_fieldset
|
26
|
+
search_fields = fields.select {|f| f.column && !conditions_fields.include?(f) && search_types.include?(f.column_type)}
|
27
|
+
all_fields = conditions_fields + search_fields
|
18
28
|
|
19
|
-
|
29
|
+
scope = scope.includes(includes(all_fields)).includes(reflection_includes(fields)).where(searches(search_fields, options[:search])).order(order)
|
30
|
+
|
31
|
+
conditions.each do |name, value|
|
20
32
|
field = conditions_fields[name]
|
21
|
-
|
22
|
-
|
33
|
+
scope = if value.is_a?(Puffer::Filters::Diapason)
|
34
|
+
case
|
35
|
+
when value.from.blank? then scope.where(["#{query_column(field)} < ?", value.till])
|
36
|
+
when value.till.blank? then scope.where(["#{query_column(field)} > ?", value.from])
|
37
|
+
else scope.where(name => Range.new(value.from, value.till))
|
38
|
+
end
|
39
|
+
else
|
40
|
+
scope.where(name => value)
|
41
|
+
end if field
|
23
42
|
end
|
24
43
|
|
25
|
-
|
26
|
-
|
27
|
-
scope.includes(includes(all_fields)).where(searches(search_fields, options[:search])).where(conditions).order(order)
|
44
|
+
scope
|
28
45
|
end
|
29
46
|
|
30
47
|
private
|
@@ -37,8 +54,20 @@ module Puffer
|
|
37
54
|
fields.map {|f| f.path unless f.native?}.compact.to_includes
|
38
55
|
end
|
39
56
|
|
57
|
+
def reflection_includes fields
|
58
|
+
fields.map {|f| f.field_name if f.reflection}.compact.to_includes
|
59
|
+
end
|
60
|
+
|
40
61
|
def searches fields, query
|
41
|
-
[fields.map {|f| "#{f
|
62
|
+
[fields.map {|f| "#{query_column(f)} like ?"}.compact.join(' or '), *(Array.wrap("%#{query}%") * fields.count)] if query.present?
|
63
|
+
end
|
64
|
+
|
65
|
+
def query_column field
|
66
|
+
"#{field.model.table_name}.#{field.name}" if field.column
|
67
|
+
end
|
68
|
+
|
69
|
+
def query_order field
|
70
|
+
field.options[:order] || query_column(field)
|
42
71
|
end
|
43
72
|
|
44
73
|
end
|
@@ -8,22 +8,41 @@ module Puffer
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def reflection name
|
12
|
+
reflection = klass.reflect_on_association(name.to_sym)
|
13
|
+
Reflection.new(
|
14
|
+
:klass => reflection.klass,
|
15
|
+
:macro => reflection.macro,
|
16
|
+
:through? => false
|
17
|
+
) if reflection
|
18
|
+
end
|
19
|
+
|
11
20
|
def filter scope, fields, options = {}
|
12
|
-
fields = fields.columns
|
13
21
|
conditions, order = extract_conditions_and_order!(options)
|
14
22
|
|
15
|
-
|
16
|
-
|
23
|
+
order = order.map { |o| f = fields[o.first]; [query_order(f), o.last] if f && f.column }.compact
|
24
|
+
|
25
|
+
conditions_fields = fields.select {|f| f.column && conditions.keys.include?(f.field_name)}.to_fieldset
|
26
|
+
search_fields = fields.select {|f| f.column && !conditions_fields.include?(f) && search_types.include?(f.column_type)}
|
17
27
|
all_fields = conditions_fields + search_fields
|
28
|
+
|
29
|
+
scope = scope.any_of(searches(search_fields, options[:search])) if options[:search].present?
|
30
|
+
scope = scope.order_by(order)
|
18
31
|
|
19
|
-
conditions
|
32
|
+
conditions.each do |name, value|
|
20
33
|
field = conditions_fields[name]
|
21
|
-
|
22
|
-
|
34
|
+
scope = if value.is_a?(Puffer::Filters::Diapason)
|
35
|
+
case
|
36
|
+
when value.from.blank? then scope.where(name.to_sym.lt => value.till)
|
37
|
+
when value.till.blank? then scope.where(name.to_sym.gt => value.from)
|
38
|
+
else scope.where(name => Range.new(value.from, value.till))
|
39
|
+
end
|
40
|
+
else
|
41
|
+
scope.where(name => value)
|
42
|
+
end if field
|
23
43
|
end
|
24
44
|
|
25
|
-
scope
|
26
|
-
scope.where(conditions).order(order)
|
45
|
+
scope
|
27
46
|
end
|
28
47
|
|
29
48
|
private
|
@@ -34,7 +53,11 @@ module Puffer
|
|
34
53
|
|
35
54
|
def searches fields, query
|
36
55
|
regexp = /#{Regexp.escape(query)}/i
|
37
|
-
fields.map {|field| {field.
|
56
|
+
fields.map {|field| {field.to_s => regexp}}
|
57
|
+
end
|
58
|
+
|
59
|
+
def query_order field
|
60
|
+
field.options[:order] || field.name
|
38
61
|
end
|
39
62
|
|
40
63
|
end
|
data/lib/puffer/resource/node.rb
CHANGED
@@ -5,38 +5,52 @@ module Puffer
|
|
5
5
|
include ActionController::UrlFor
|
6
6
|
include Rails.application.routes.url_helpers
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def collection_method routing_type, options = {}
|
9
|
+
send url_method_name(routing_type, url_segment, options.delete(:action)), *url_arguments, options
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
12
|
+
def member_method routing_type, *args
|
13
|
+
options = args.extract_options!
|
14
|
+
send url_method_name(routing_type, singular, options.delete(:action)), *url_arguments(use_resource_id(args.first) || member_id), options
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def new_method routing_type, options = {}
|
18
|
+
send url_method_name(routing_type, singular, :new), *url_arguments, options
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
21
|
+
def edit_method routing_type, *args
|
22
|
+
options = args.extract_options!
|
23
|
+
member_method routing_type, *args, options.merge(:action => :edit)
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
|
28
|
-
resource = Array.wrap(args)
|
29
|
-
return [scope] + ancestors.map(&:route_member) + resource, options
|
26
|
+
def url_method_name routing_type, current, action = nil
|
27
|
+
[action, scope, *ancestors.map(&:singular), current, routing_type].compact.join('_')
|
30
28
|
end
|
31
29
|
|
32
|
-
def
|
33
|
-
|
30
|
+
def url_arguments current = nil
|
31
|
+
ancestors.map(&:member_id).push(current).compact
|
32
|
+
end
|
33
|
+
|
34
|
+
%w(url path).each do |routing_type|
|
35
|
+
%w(collection member new edit).each do |method|
|
36
|
+
define_method "#{method}_#{routing_type}" do |*args|
|
37
|
+
send "#{method}_method", routing_type, *args
|
38
|
+
end
|
39
|
+
end
|
34
40
|
end
|
35
41
|
|
36
42
|
def default_url_options *args
|
37
43
|
Puffer::Base.default_url_options(*args)
|
38
44
|
end
|
39
45
|
|
46
|
+
def use_resource_id(resource)
|
47
|
+
if resource and resource.respond_to?(:id)
|
48
|
+
resource.id
|
49
|
+
else
|
50
|
+
resource
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
40
54
|
end
|
41
55
|
end
|
42
56
|
end
|
data/lib/puffer/resource.rb
CHANGED
@@ -11,7 +11,7 @@ module Puffer
|
|
11
11
|
include Routing
|
12
12
|
|
13
13
|
attr_reader :resource_node, :scope, :params, :controller_instance
|
14
|
-
delegate :controller, :name, :plural?, :to => :resource_node, :allow_nil => true
|
14
|
+
delegate :controller, :name, :plural?, :singular, :plural, :url_segment, :to => :resource_node, :allow_nil => true
|
15
15
|
delegate :model, :to => :controller, :allow_nil => true
|
16
16
|
delegate :env, :request, :to => :controller_instance, :allow_nil => true
|
17
17
|
|
@@ -51,14 +51,10 @@ module Puffer
|
|
51
51
|
resource_node.ancestors[0..-2].each do |ancestor|
|
52
52
|
key = ancestor.to_s.singularize.foreign_key
|
53
53
|
parent_params[key] = params[key] if params[key]
|
54
|
-
key = key.gsub(/_id$/, '_member')
|
55
|
-
parent_params[key] = params[key] if params[key]
|
56
54
|
end
|
57
55
|
|
58
56
|
key = resource_node.parent.to_s.singularize.foreign_key
|
59
57
|
parent_params[:id] = params[key] if params[key]
|
60
|
-
key = key.gsub(/_id$/, '_member')
|
61
|
-
parent_params[:member] = params[key] if params[key]
|
62
58
|
|
63
59
|
self.class.new parent_params, controller_instance
|
64
60
|
end
|
@@ -72,14 +68,10 @@ module Puffer
|
|
72
68
|
resource_node.ancestors.each do |ancestor|
|
73
69
|
key = ancestor.to_s.singularize.foreign_key
|
74
70
|
child_params[key] = params[key] if params[key]
|
75
|
-
key = key.gsub(/_id$/, '_member')
|
76
|
-
child_params[key] = params[key] if params[key]
|
77
71
|
end
|
78
72
|
|
79
73
|
key = resource_node.to_s.singularize.foreign_key
|
80
74
|
child_params[key] = params[:id] if params[:id]
|
81
|
-
key = key.gsub(/_id$/, '_member')
|
82
|
-
child_params[key] = params[:member] if params[:member]
|
83
75
|
|
84
76
|
self.class.new child_params, controller_instance
|
85
77
|
end
|
@@ -92,31 +84,40 @@ module Puffer
|
|
92
84
|
end
|
93
85
|
end
|
94
86
|
|
87
|
+
def member_id
|
88
|
+
params[:id]
|
89
|
+
end
|
90
|
+
|
95
91
|
def collection_scope
|
96
92
|
parent ? parent.member.send(name) : model
|
97
93
|
end
|
98
94
|
|
95
|
+
def adapter
|
96
|
+
model.to_adapter
|
97
|
+
end
|
98
|
+
|
99
99
|
def collection
|
100
|
-
|
100
|
+
scope = collection_scope
|
101
|
+
scope = scope.send controller.configuration.scope if controller.configuration.scope
|
102
|
+
adapter.filter scope, controller.filter_fields,
|
101
103
|
:conditions => controller_instance.puffer_filters.conditions,
|
102
104
|
:search => controller_instance.puffer_filters.search,
|
103
105
|
:order => controller_instance.puffer_filters.order
|
104
106
|
end
|
105
107
|
|
106
108
|
def member
|
107
|
-
return params[:member] if params[:member]
|
108
109
|
if parent
|
109
110
|
if plural?
|
110
|
-
parent.member.send(name).find
|
111
|
+
parent.member.send(name).find member_id if member_id
|
111
112
|
else
|
112
113
|
parent.member.send(name)
|
113
114
|
end
|
114
115
|
else
|
115
|
-
|
116
|
+
adapter.get member_id if member_id
|
116
117
|
end
|
117
118
|
end
|
118
119
|
|
119
|
-
def new_member
|
120
|
+
def new_member attributes = attributes
|
120
121
|
if parent
|
121
122
|
if plural?
|
122
123
|
parent.member.send(name).new attributes
|
@@ -129,15 +130,14 @@ module Puffer
|
|
129
130
|
end
|
130
131
|
|
131
132
|
def attributes
|
132
|
-
params[
|
133
|
+
params[attributes_key] || {}
|
134
|
+
end
|
135
|
+
|
136
|
+
def attributes_key
|
137
|
+
model.model_name.param_key
|
133
138
|
end
|
134
139
|
|
135
140
|
def method_missing method, *args, &block
|
136
|
-
method = method.to_s
|
137
|
-
if method.match(/path$/) && respond_to?(method.gsub(/path$/, 'url'))
|
138
|
-
options = args.extract_options!
|
139
|
-
return send method.gsub(/path$/, 'url'), *(args << options.merge(:routing_type => :path))
|
140
|
-
end
|
141
141
|
model.send method, *args, &block if model.respond_to? method
|
142
142
|
end
|
143
143
|
|