qm-acts-as-generic-controller 0.0.18 → 0.1.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/Rakefile CHANGED
@@ -9,9 +9,10 @@ begin
9
9
  gemspec.email = "marcin@saepia.net"
10
10
  gemspec.homepage = "http://q.saepia.net"
11
11
  gemspec.authors = ["Marcin Lewandowski"]
12
- gemspec.version = "0.0.18"
12
+ gemspec.version = "0.1.0"
13
13
  gemspec.files = Rake::FileList.new [ "MIT-LICENSE", "Rakefile", "lib/*", "app/views/generic_controller/*" ]
14
14
  gemspec.add_dependency "qui-common-helpers", ">= 0.0.7"
15
+ gemspec.add_dependency "qui-index-table", ">= 0.0.8"
15
16
  gemspec.add_dependency "qui-tabs", ">= 0.0.3"
16
17
  gemspec.add_dependency "qui-toolbar", ">= 0.0.4"
17
18
  gemspec.add_dependency "rfc822"
@@ -1,13 +1,13 @@
1
1
  <%- records ||= instance_variable_get("@#{@controller.class.to_s.demodulize.gsub("Controller", "").tableize}") -%>
2
2
  <%- class_name ||= @controller.class.to_s.demodulize.gsub("Controller", "").singularize.constantize -%>
3
3
 
4
- <%- headers = class_name.generic_fields.collect{|x| x.is_a?(Hash) ? ".#{x.keys.first}".to_sym : ".#{x}".to_sym} -%>
4
+ <%- headers = class_name.generic_fields(:action => :index).collect{ |x| x[:options][:index_header] || ".#{x[:name]}".to_sym } -%>
5
5
  <%- controller_name = "#{defined?(section) ? "#{section.to_s.camelize}::" : ""}#{class_name.to_s.pluralize}".tableize %>
6
6
  <%- has_edit = ActionController::Routing::Routes.routes.collect{|x| x if x.matches_controller_and_action?(controller_name, "edit") }.compact.size > 0 %>
7
7
  <%- has_delete = ActionController::Routing::Routes.routes.collect{|x| x if x.matches_controller_and_action?(controller_name, "destroy") }.compact.size > 0 %>
8
8
 
9
9
  <%- if defined?(QM::ActsAsWorkflow) and class_name.is_workflow? -%>
10
- <%- headers << :"#{section}.workflow.common.indexTableHeader" -%>
10
+ <%- headers << :"workflow.common.indexTableHeader" -%>
11
11
  <%- end -%>
12
12
 
13
13
  <%- if defined?(QUI::IndexTable) -%>
@@ -16,8 +16,14 @@
16
16
  <%- headers << :oneicon if has_delete %>
17
17
 
18
18
  <%- index_table records, :headers => headers, :class_name => class_name do |r| %>
19
- <%- class_name.generic_fields.each do |field| -%>
20
- <td><%= render :partial => "generic_controller/data", :locals => { :record => r, :field => field } %></td>
19
+ <%- class_name.generic_fields(:action => :index).each do |field| -%>
20
+ <td>
21
+ <%- if field[:options].has_key? :renderer -%>
22
+ <%= send(field[:options][:renderer], { :record => r, :field => field, :action => :index }) %>
23
+ <%- else -%>
24
+ <%= generic_renderer(:index, { :record => r, :field => field }) %>
25
+ <%- end -%>
26
+ </td>
21
27
  <%- end -%>
22
28
 
23
29
  <%- if defined?(QM::ActsAsWorkflow) and class_name.is_workflow? -%>
@@ -14,65 +14,58 @@
14
14
  <%- end -%>
15
15
 
16
16
  <ol>
17
- <%- klass.generic_fields.each do |field| -%>
18
- <%- if field.is_a? Hash -%>
19
- <%- attribute_name = field.keys.first.to_sym -%>
20
- <%- else -%>
21
- <%- attribute_name = field.to_sym -%>
22
- <%- end -%>
23
-
24
-
25
- <%- is_association = klass.generic_field_associations[attribute_name].present? -%>
26
- <%- association = klass.generic_field_associations[attribute_name] if is_association -%>
17
+ <%- klass.generic_fields(:action => :form).each do |field| -%>
18
+ <%- is_association = klass.generic_field_associations[field[:name]].present? -%>
19
+ <%- association = klass.generic_field_associations[field[:name]] if is_association -%>
27
20
  <%- is_writable = (not is_association or (is_association and not association[:readonly])) -%>
28
21
  <%- if is_writable -%>
29
22
  <%- if is_association -%>
30
- <%- if klass.generic_field_associations[attribute_name][:kind] == :has_many or klass.generic_field_associations[attribute_name][:kind] == :has_and_belongs_to_many -%>
31
- <%- is_accessible = klass.attr_accessible.include?("#{attribute_name.to_s.singularize}_ids") -%>
32
- <%- elsif klass.generic_field_associations[attribute_name][:kind] == :belongs_to -%>
23
+ <%- if klass.generic_field_associations[field[:name]][:kind] == :has_many or klass.generic_field_associations[field[:name]][:kind] == :has_and_belongs_to_many -%>
24
+ <%- is_accessible = klass.attr_accessible.include?("#{field[:name].to_s.singularize}_ids") -%>
25
+ <%- elsif klass.generic_field_associations[field[:name]][:kind] == :belongs_to -%>
33
26
  <%- is_accessible = klass.attr_accessible.include?(association[:foreign_key].to_s) -%>
34
27
  <%- end -%>
35
28
  <%- else -%>
36
- <%- is_accessible = klass.attr_accessible.include?(attribute_name.to_s) -%>
29
+ <%- is_accessible = klass.attr_accessible.include?(field[:name].to_s) -%>
37
30
  <%- end -%>
38
31
  <%- end -%>
39
32
 
40
33
 
41
34
  <%- if is_accessible -%>
42
35
  <li>
43
- <%= f.label attribute_name %>
36
+ <%= f.label field[:name] %>
44
37
 
45
38
  <%- if field.is_a?(Hash) and field.values.first == :enum -%>
46
- <%= f.select attribute_name, t("activerecord.enums.#{table_name}.#{attribute_name}").collect{|k,v| [v, k.to_s] }.sort{|x,y| x.last.to_i <=> y.last.to_i }, { :selected => params[table_name] ? params[table_name][attribute_name].to_s : f.object.send(attribute_name).to_s } %>
39
+ <%= f.select field[:name], t("activerecord.enums.#{table_name}.#{field[:name]}").collect{|k,v| [v, k.to_s] }.sort{|x,y| x.last.to_i <=> y.last.to_i }, { :selected => params[table_name] ? params[table_name][field[:name]].to_s : f.object.send(field[:name]).to_s } %>
47
40
 
48
- <%- elsif klass.generic_field_associations[attribute_name] -%>
49
- <%- if klass.generic_field_associations[attribute_name][:kind] == :belongs_to -%>
41
+ <%- elsif klass.generic_field_associations[field[:name]] -%>
42
+ <%- if klass.generic_field_associations[field[:name]][:kind] == :belongs_to -%>
50
43
  <%= multiple_select :kind => :radio, :field => field, :record => record %>
51
44
 
52
- <%- elsif klass.generic_field_associations[attribute_name][:kind] == :has_and_belongs_to_many or klass.generic_field_associations[attribute_name][:kind] == :has_many-%>
45
+ <%- elsif klass.generic_field_associations[field[:name]][:kind] == :has_and_belongs_to_many or klass.generic_field_associations[field[:name]][:kind] == :has_many-%>
53
46
  <%= multiple_select :kind => :check, :field => field, :record => record %>
54
47
 
55
48
  <%- end -%>
56
49
 
57
50
  <%- else -%>
58
- <%- case record.column_for_attribute(attribute_name).type -%>
51
+ <%- case record.column_for_attribute(field[:name]).type -%>
59
52
  <%- when :text -%>
60
- <%= f.text_area attribute_name, :rows => 5, :cols => 60 %>
53
+ <%= f.text_area field[:name], :rows => 5, :cols => 60 %>
61
54
  <%- when :date, :datetime -%>
62
- <%= f.calendar_date_select attribute_name %>
55
+ <%= f.calendar_date_select field[:name] %>
63
56
  <%- when :boolean -%>
64
57
  <span class="boolean">
65
- <%= f.radio_button attribute_name, "1", { :checked => params[table_name] && params[table_name].has_key?(attribute_name) ? params[table_name][attribute_name] == "1" : f.object.send(attribute_name) == true } %><%= f.label attribute_name, t(:"genericController.yesAsBooleanOption"), { :for => "#{f.object.class.to_s.tableize.singularize}_#{attribute_name}_1" } %>
66
- <%= f.radio_button attribute_name, "0", { :checked => params[table_name] && params[table_name].has_key?(attribute_name) ? params[table_name][attribute_name] == "0" : f.object.send(attribute_name) == false } %><%= f.label attribute_name, t(:"genericController.noAsBooleanOption"), { :for => "#{f.object.class.to_s.tableize.singularize}_#{attribute_name}_0" } %>
58
+ <%= f.radio_button field[:name], "1", { :checked => params[table_name] && params[table_name].has_key?(field[:name]) ? params[table_name][field[:name]] == "1" : f.object.send(field[:name]) == true } %><%= f.label field[:name], t(:"genericController.yesAsBooleanOption"), { :for => "#{f.object.class.to_s.tableize.singularize}_#{field[:name]}_1" } %>
59
+ <%= f.radio_button field[:name], "0", { :checked => params[table_name] && params[table_name].has_key?(field[:name]) ? params[table_name][field[:name]] == "0" : f.object.send(field[:name]) == false } %><%= f.label field[:name], t(:"genericController.noAsBooleanOption"), { :for => "#{f.object.class.to_s.tableize.singularize}_#{field[:name]}_0" } %>
67
60
  </span>
68
61
 
69
62
  <%- else -%>
70
63
 
71
- <%- if record.respond_to?(attribute_name) and record.respond_to?("#{attribute_name}_file_name") and record.respond_to?("#{attribute_name}_content_type") -%>
72
- <%= f.file_field attribute_name %>
64
+ <%- if record.respond_to?(field[:name]) and record.respond_to?("#{field[:name]}_file_name") and record.respond_to?("#{field[:name]}_content_type") -%>
65
+ <%= f.file_field field[:name] %>
73
66
 
74
67
  <%- else -%>
75
- <%= f.text_field attribute_name %>
68
+ <%= f.text_field field[:name] %>
76
69
  <%- end -%>
77
70
  <%- end -%>
78
71
  <%- end -%>
@@ -17,7 +17,7 @@
17
17
  <%- content_tag(:div, :class => "index_scopes") do -%>
18
18
  <%- form_tag params, :method => :get do -%>
19
19
  <%- class_name.named_scopes.each do |identifier, options| -%>
20
- <%- if options.has_key?(:generic) and options[:generic] == true -%>
20
+ <%- if options.is_a?(Hash) and options.has_key?(:generic) and options[:generic] == true -%>
21
21
  <%= check_box_tag "scopes[]", identifier, params[:scopes] && params[:scopes].include?(identifier.to_s), :id => "scope_#{class_name}_#{identifier}" %>
22
22
  <%= label_tag "scope_#{class_name}_#{identifier}", t(:"#{section}.scopes.#{class_name.to_s.tableize.singularize}.#{identifier}") %>
23
23
  <%- end -%>
@@ -13,16 +13,16 @@
13
13
 
14
14
  <%- description = capture do -%>
15
15
  <dl>
16
- <%- klass.generic_fields.each do |field| -%>
17
- <%- if field.is_a? Hash -%>
18
- <%- attribute_name = field.keys.first.to_sym -%>
19
- <%- else -%>
20
- <%- attribute_name = field.to_sym -%>
21
- <%- end -%>
22
-
23
- <dt><%= h klass.human_attribute_name attribute_name %></dt>
24
-
25
- <dd><%= render :partial => "generic_controller/data", :locals => { :record => record, :field => field } %></dd>
16
+ <%- klass.generic_fields(:action => :show).each do |field| -%>
17
+ <dt><%= h klass.human_attribute_name field[:name] %></dt>
18
+
19
+ <dd>
20
+ <%- if field[:options].has_key? :renderer -%>
21
+ <%= send(field[:options][:renderer], { :record => record, :field => field, :action => :show }) %>
22
+ <%- else -%>
23
+ <%= generic_renderer(:show, { :record => record, :field => field }) %>
24
+ <%- end -%>
25
+ </dd>
26
26
  <%- end -%>
27
27
  </dl>
28
28
  <%- end -%>
@@ -8,7 +8,7 @@ module QM
8
8
 
9
9
  module ClassMethods
10
10
  def generic_field_associations
11
- @generic_field_associations
11
+ @generic_field_associations || {}
12
12
  end
13
13
 
14
14
  def has_many(association_id, options = {}, &extension)
@@ -46,7 +46,7 @@ module QM
46
46
 
47
47
  def generic_named_scopes
48
48
  scopes = {}
49
- named_scopes.each{ |i, o| scopes[i] = o if o.has_key?(:generic) and o[:generic] }
49
+ named_scopes.each{ |i, o| scopes[i] = o if o.is_a? Hash and o.has_key?(:generic) and o[:generic] } # TODO creating generic named_scopes with lambdas
50
50
  scopes
51
51
  end
52
52
 
@@ -65,16 +65,34 @@ module QM
65
65
 
66
66
 
67
67
 
68
- def generic_fields
69
- @generic_fields || []
68
+ def generic_fields(options = {})
69
+ @generic_fields ||= {}
70
+ if options.has_key? :action
71
+ @generic_fields[options[:action]] || []
72
+ else
73
+ @generic_fields || []
74
+ end
70
75
  end
71
76
 
72
77
  def generic_form_fieldsets
73
78
  @generic_form_fieldsets
74
79
  end
75
-
76
- def has_generic_fields(*fields)
77
- @generic_fields = fields.flatten
80
+
81
+ def has_generic_field_for(actions, name, options = {})
82
+ options = options.symbolize_keys!
83
+ @generic_fields ||= {}
84
+
85
+ if actions.is_a? Array
86
+ actions.each do |action|
87
+ raise ArgumentError, "action must be one of :index, :show, :form" unless [ :index, :show, :form ].include? action.to_sym
88
+ @generic_fields[action.to_sym] ||= []
89
+ @generic_fields[action.to_sym] << { :name => name.to_sym, :options => options }
90
+ end
91
+ else
92
+ raise ArgumentError, "action must be one of :index, :show, :form" unless [ :index, :show, :form ].include? actions.to_sym
93
+ @generic_fields[actions.to_sym] ||= []
94
+ @generic_fields[actions.to_sym] << { :name => name.to_sym, :options => options }
95
+ end
78
96
  end
79
97
 
80
98
  def has_generic_form_fieldsets(*fieldsets)
@@ -1,6 +1,33 @@
1
1
  module QM
2
2
  module ActsAsGenericController
3
3
  module ViewIncludes
4
+ def generic_renderer(action, options = {})
5
+
6
+ data = options[:record].send options[:field][:name]
7
+
8
+ result = ""
9
+
10
+ if data.is_a?(ActiveRecord::Base)
11
+ result = link_to_object options[:record].send(options[:field][:name])
12
+
13
+ elsif data.is_a?(Array) and data.first.is_a?(ActiveRecord::Base)
14
+ result = data.collect{ |x| link_to_object(x) }.sort_alphabetical.join(", ")
15
+
16
+ elsif defined?(RFC822) and data.is_a?(String) and data =~ RFC822::EMAIL_REGEXP_WHOLE
17
+ result = link_to data, "mailto:#{data}"
18
+
19
+ else
20
+ result = h data
21
+ end
22
+
23
+
24
+ puts options.inspect
25
+
26
+ result = link_to_object options[:record], result if options[:field][:options][:link_to] == :show
27
+
28
+ result
29
+ end
30
+
4
31
  def multiple_select(options = {})
5
32
  options.symbolize_keys!
6
33
  options[:item] ||= {}
@@ -9,11 +36,7 @@ module QM
9
36
  @multiple_select_count += 1
10
37
 
11
38
  if options.has_key?(:field) and not options[:field].nil? and options.has_key?(:record) and options[:record].is_a? ActiveRecord::Base
12
- if options[:field].is_a? Hash
13
- attribute_name = options[:field].keys.first.to_sym
14
- else
15
- attribute_name = options[:field].to_sym
16
- end
39
+ attribute_name = options[:field][:name]
17
40
 
18
41
  klass = options[:record].class
19
42
  table_name = klass.to_s.tableize.singularize
@@ -27,7 +50,7 @@ module QM
27
50
  allow_nil ||= options[:record].column_for_attribute(klass.generic_field_associations[attribute_name][:foreign_key]).null
28
51
  end
29
52
 
30
- if klass.respond_to? :limit_for_user and defined?(current_user)
53
+ if klass.generic_field_associations[attribute_name][:class_name].respond_to? :limit_for_user and defined?(current_user)
31
54
  collection = klass.generic_field_associations[attribute_name][:class_name].limit_for_user(current_user)
32
55
  else
33
56
  collection = klass.generic_field_associations[attribute_name][:class_name].all
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qm-acts-as-generic-controller
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 18
10
- version: 0.0.18
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Marcin Lewandowski
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-14 00:00:00 +02:00
18
+ date: 2010-10-19 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -35,9 +35,25 @@ dependencies:
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
38
- name: qui-tabs
38
+ name: qui-index-table
39
39
  prerelease: false
40
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 15
46
+ segments:
47
+ - 0
48
+ - 0
49
+ - 8
50
+ version: 0.0.8
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: qui-tabs
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
41
57
  none: false
42
58
  requirements:
43
59
  - - ">="
@@ -49,11 +65,11 @@ dependencies:
49
65
  - 3
50
66
  version: 0.0.3
51
67
  type: :runtime
52
- version_requirements: *id002
68
+ version_requirements: *id003
53
69
  - !ruby/object:Gem::Dependency
54
70
  name: qui-toolbar
55
71
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
72
+ requirement: &id004 !ruby/object:Gem::Requirement
57
73
  none: false
58
74
  requirements:
59
75
  - - ">="
@@ -65,11 +81,11 @@ dependencies:
65
81
  - 4
66
82
  version: 0.0.4
67
83
  type: :runtime
68
- version_requirements: *id003
84
+ version_requirements: *id004
69
85
  - !ruby/object:Gem::Dependency
70
86
  name: rfc822
71
87
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
88
+ requirement: &id005 !ruby/object:Gem::Requirement
73
89
  none: false
74
90
  requirements:
75
91
  - - ">="
@@ -79,11 +95,11 @@ dependencies:
79
95
  - 0
80
96
  version: "0"
81
97
  type: :runtime
82
- version_requirements: *id004
98
+ version_requirements: *id005
83
99
  - !ruby/object:Gem::Dependency
84
100
  name: sort_alphabetical
85
101
  prerelease: false
86
- requirement: &id005 !ruby/object:Gem::Requirement
102
+ requirement: &id006 !ruby/object:Gem::Requirement
87
103
  none: false
88
104
  requirements:
89
105
  - - ">="
@@ -93,11 +109,11 @@ dependencies:
93
109
  - 0
94
110
  version: "0"
95
111
  type: :runtime
96
- version_requirements: *id005
112
+ version_requirements: *id006
97
113
  - !ruby/object:Gem::Dependency
98
114
  name: calendar_date_select
99
115
  prerelease: false
100
- requirement: &id006 !ruby/object:Gem::Requirement
116
+ requirement: &id007 !ruby/object:Gem::Requirement
101
117
  none: false
102
118
  requirements:
103
119
  - - ">="
@@ -107,7 +123,7 @@ dependencies:
107
123
  - 0
108
124
  version: "0"
109
125
  type: :runtime
110
- version_requirements: *id006
126
+ version_requirements: *id007
111
127
  description: "qM: generates generic controller actions and views"
112
128
  email: marcin@saepia.net
113
129
  executables: []
@@ -119,7 +135,6 @@ extra_rdoc_files:
119
135
  files:
120
136
  - MIT-LICENSE
121
137
  - Rakefile
122
- - app/views/generic_controller/_data.erb
123
138
  - app/views/generic_controller/_index_table.erb
124
139
  - app/views/generic_controller/_multiple_select.erb
125
140
  - app/views/generic_controller/form.erb
@@ -1,26 +0,0 @@
1
- <%- if field.is_a? Hash -%>
2
- <%- attribute_name = field.keys.first.to_sym -%>
3
- <%- else -%>
4
- <%- attribute_name = field.to_sym -%>
5
- <%- end -%>
6
-
7
- <%- data = record.send attribute_name -%>
8
-
9
- <%- if data.is_a?(ActiveRecord::Base) -%>
10
- <%= link_to_object record.send(field) %>
11
-
12
- <%- elsif data.is_a?(Array) and data.first.is_a?(ActiveRecord::Base) -%>
13
- <%= data.collect{ |x| link_to_object(x) }.sort_alphabetical.join(", ") %>
14
-
15
- <%- elsif field.is_a?(Hash) and field.values.first == :link_to_show -%>
16
- <%= link_to_object record, data %>
17
-
18
- <%- elsif field.is_a?(Hash) and field.values.first == :enum -%>
19
- <%= h record.enum_human_value attribute_name %>
20
-
21
- <%- elsif data.is_a?(String) and data =~ RFC822::EMAIL_REGEXP_WHOLE -%>
22
- <%= link_to data, "mailto:#{data}" %>
23
-
24
- <%- else -%>
25
- <%= h data %>
26
- <%- end -%>