administer 0.2.2 → 0.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.
Files changed (120) hide show
  1. data/README.rdoc +3 -4
  2. data/app/controllers/administer/application_controller.rb +12 -0
  3. data/app/controllers/administer/entities_controller.rb +76 -0
  4. data/app/helpers/administer/dashboard_helper.rb +1 -1
  5. data/app/helpers/administer/entities_helper.rb +2 -0
  6. data/app/views/administer/dashboard/index.html.haml +1 -1
  7. data/app/views/administer/entities/_form.haml +9 -0
  8. data/app/views/administer/entities/edit.html.haml +9 -0
  9. data/app/views/administer/entities/index.html.haml +21 -0
  10. data/app/views/administer/entities/new.haml +9 -0
  11. data/app/views/administer/fields/_belongs_to.html.haml +2 -0
  12. data/app/views/administer/fields/_date_select.html.haml +2 -0
  13. data/app/views/administer/fields/_has_many.html.haml +4 -0
  14. data/app/views/administer/fields/_has_one.html.haml +2 -0
  15. data/app/views/administer/fields/_text_area.html.haml +2 -0
  16. data/app/views/administer/fields/_text_field.html.haml +2 -0
  17. data/app/views/administer/shared/_errors.html.haml +6 -0
  18. data/app/views/layouts/administer.html.haml +21 -0
  19. data/config/routes.rb +4 -4
  20. data/lib/administer.rb +1 -0
  21. data/lib/administer/active_record.rb +22 -0
  22. data/lib/administer/config.rb +37 -0
  23. data/lib/administer/config/controller_config.rb +24 -0
  24. data/lib/administer/config/model_config.rb +23 -0
  25. data/lib/administer/engine.rb +5 -0
  26. data/lib/administer/fields.rb +34 -0
  27. data/lib/administer/fields/association.rb +21 -0
  28. data/lib/administer/fields/base.rb +15 -0
  29. data/lib/administer/fields/belongs_to.rb +12 -0
  30. data/lib/administer/fields/date_select.rb +6 -0
  31. data/lib/administer/fields/field_builder.rb +25 -0
  32. data/lib/administer/fields/has_many.rb +22 -0
  33. data/lib/administer/fields/has_one.rb +24 -0
  34. data/lib/administer/fields/text_area.rb +6 -0
  35. data/lib/administer/fields/text_field.rb +6 -0
  36. data/lib/administer/model.rb +40 -13
  37. data/spec/controllers/administer/entities_controller_spec.rb +23 -0
  38. data/spec/{rails_root/spec/controllers → controllers}/posts_controller_spec.rb +1 -1
  39. data/spec/factories/categories.rb +3 -0
  40. data/spec/factories/comments.rb +3 -0
  41. data/spec/{rails_root/spec/factories → factories}/posts.rb +0 -0
  42. data/spec/lib/config/model_config_spec.rb +35 -0
  43. data/spec/lib/config_spec.rb +29 -0
  44. data/spec/lib/fields/field_builder_spec.rb +10 -0
  45. data/spec/{rails_root/spec/models/administer → lib}/model_spec.rb +5 -4
  46. data/spec/models/comment_spec.rb +5 -0
  47. data/spec/rails_root/Gemfile +2 -0
  48. data/spec/rails_root/Gemfile.lock +150 -0
  49. data/spec/rails_root/README +256 -0
  50. data/spec/rails_root/Rakefile +7 -0
  51. data/spec/rails_root/app/controllers/application_controller.rb +4 -0
  52. data/spec/rails_root/app/models/attachment.rb +3 -0
  53. data/spec/rails_root/app/models/category.rb +1 -0
  54. data/spec/rails_root/app/models/comment.rb +3 -0
  55. data/spec/rails_root/app/models/post.rb +8 -0
  56. data/spec/rails_root/app/views/layouts/application.html.erb +14 -0
  57. data/spec/rails_root/app/views/posts/_form.html.haml +19 -0
  58. data/spec/rails_root/app/views/posts/edit.html.haml +5 -0
  59. data/spec/rails_root/app/views/posts/index.html.haml +10 -0
  60. data/spec/rails_root/app/views/posts/new.html.haml +3 -0
  61. data/spec/rails_root/app/views/posts/show.html.haml +10 -0
  62. data/spec/rails_root/config.ru +4 -0
  63. data/spec/rails_root/config/cucumber.yml +8 -0
  64. data/spec/rails_root/config/database.yml +25 -0
  65. data/spec/rails_root/config/initializers/administer.rb +23 -0
  66. data/spec/rails_root/config/locales/en.yml +5 -0
  67. data/spec/rails_root/db/development.sqlite3 +0 -0
  68. data/spec/rails_root/db/migrate/20110104100347_add_publish_on_to_post.rb +9 -0
  69. data/spec/rails_root/db/migrate/20110214190645_add_category_to_post.rb +9 -0
  70. data/spec/rails_root/db/migrate/20110609184125_create_comments.rb +13 -0
  71. data/spec/rails_root/db/migrate/20110628215407_create_attachments.rb +13 -0
  72. data/spec/rails_root/db/schema.rb +44 -0
  73. data/spec/rails_root/db/test.sqlite3 +0 -0
  74. data/spec/rails_root/features/administer/dashboard.feature +15 -0
  75. data/spec/rails_root/features/administer/posts.feature +72 -0
  76. data/spec/rails_root/features/listing_posts.feature +15 -0
  77. data/spec/rails_root/features/managing_posts.feature +70 -0
  78. data/spec/rails_root/features/step_definitions/categories_steps.rb +6 -0
  79. data/spec/rails_root/features/step_definitions/comments_steps.rb +6 -0
  80. data/spec/rails_root/features/step_definitions/post_steps.rb +21 -0
  81. data/spec/rails_root/features/step_definitions/web_steps.rb +5 -2
  82. data/spec/rails_root/features/support/env.rb +32 -46
  83. data/spec/rails_root/features/support/factory_girl.rb +2 -0
  84. data/spec/rails_root/features/support/matchers.rb +55 -0
  85. data/spec/rails_root/features/support/paths.rb +2 -0
  86. data/spec/rails_root/features/support/selectors.rb +39 -0
  87. data/spec/rails_root/lib/tasks/cucumber.rake +65 -0
  88. data/spec/rails_root/log/development.log +19507 -0
  89. data/spec/rails_root/log/test.log +45042 -0
  90. data/spec/rails_root/public/404.html +26 -0
  91. data/spec/rails_root/public/422.html +26 -0
  92. data/spec/rails_root/public/500.html +26 -0
  93. data/spec/rails_root/public/favicon.ico +0 -0
  94. data/spec/rails_root/public/images/rails.png +0 -0
  95. data/spec/rails_root/public/javascripts/application.js +2 -0
  96. data/spec/rails_root/public/javascripts/controls.js +965 -0
  97. data/spec/rails_root/public/javascripts/dragdrop.js +974 -0
  98. data/spec/rails_root/public/javascripts/effects.js +1123 -0
  99. data/spec/rails_root/public/javascripts/prototype.js +6001 -0
  100. data/spec/rails_root/public/javascripts/rails.js +175 -0
  101. data/spec/rails_root/public/robots.txt +5 -0
  102. data/spec/rails_root/public/stylesheets/scaffold.css +60 -0
  103. data/spec/rails_root/script/cucumber +10 -0
  104. data/spec/rails_root/script/rails +6 -0
  105. data/spec/rails_root/spec/models/attachment_spec.rb +5 -0
  106. data/spec/rails_root/tmp/capybara/capybara-20101221001337.html +43 -0
  107. data/spec/rails_root/tmp/capybara/capybara-20101221001509.html +47 -0
  108. data/spec/rails_root/tmp/capybara/capybara-20110104162405.html +110 -0
  109. data/spec/rails_root/tmp/capybara/capybara-20110214224604.html +51 -0
  110. data/spec/rails_root/tmp/capybara/capybara-20110214225336.html +51 -0
  111. data/spec/rails_root/tmp/capybara/capybara-20110214225545.html +51 -0
  112. data/spec/{rails_root/spec/routing → routing}/posts_routing_spec.rb +1 -1
  113. data/spec/{rails_root/spec/spec_helper.rb → spec_helper.rb} +6 -4
  114. data/spec/{rails_root/spec/views → views}/posts/edit.html.haml_spec.rb +1 -1
  115. data/spec/{rails_root/spec/views → views}/posts/new.html.haml_spec.rb +1 -1
  116. data/spec/{rails_root/spec/views → views}/posts/show.html.haml_spec.rb +1 -1
  117. metadata +306 -46
  118. data/app/controllers/administer/models_controller.rb +0 -16
  119. data/app/views/administer/models/index.html.haml +0 -14
  120. data/spec/rails_root/spec/controllers/administer/models_controller_spec.rb +0 -19
@@ -14,10 +14,9 @@ Just go to /administer and have fun.
14
14
 
15
15
  == Running tests
16
16
  While in administer root do following:
17
- cd spec/rails_root
18
- bundle exec rspec spec/ && bundle exec cucumber features/
19
-
20
- Rake task automating this process will be delivered very soon.
17
+ rake
18
+
19
+ Default task will run all specs and features.
21
20
 
22
21
  == Copyright
23
22
 
@@ -0,0 +1,12 @@
1
+ module Administer
2
+ class ApplicationController < ::ApplicationController
3
+ layout 'administer'
4
+
5
+ before_filter :configured_filter
6
+
7
+ private
8
+ def configured_filter
9
+ self.send(:test_authorization)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,76 @@
1
+ module Administer
2
+ class EntitiesController < ApplicationController
3
+ unloadable
4
+ before_filter :set_model
5
+ before_filter :collection, :only => :index
6
+ before_filter :fields, :only => [:new, :create, :edit, :update]
7
+
8
+ def new
9
+ @object = model_class.new
10
+ end
11
+
12
+ def create
13
+ @object = model_class.new
14
+ handle_has_one
15
+ @object.attributes= @model_params
16
+ if @object.save
17
+ redirect_to administer_entities_path(:model_name => model_class.model_name)
18
+ else
19
+ render :new
20
+ end
21
+ end
22
+
23
+ def edit
24
+ @object = model_class.find(params[:id])
25
+ end
26
+
27
+ def update
28
+ @object = model_class.find(params[:id])
29
+ handle_has_one
30
+ if @object.update_attributes(@model_params)
31
+ redirect_to administer_entities_path(:model_name => model_class.model_name)
32
+ else
33
+ render :edit
34
+ end
35
+ end
36
+
37
+ def destroy
38
+ @object = model_class.find(params[:id])
39
+ unless @object.destroy
40
+ flash[:error] = "Could not destroy object."
41
+ end
42
+ redirect_to administer_entities_path(:model_name => model_class.model_name)
43
+ end
44
+
45
+ protected
46
+ def model_class
47
+ @model.entity
48
+ end
49
+ helper_method :model_class
50
+
51
+ def set_model
52
+ @model = Model.for(params[:model_name])
53
+ end
54
+
55
+ def collection
56
+ @collection = model_class.all
57
+ end
58
+
59
+ def fields
60
+ @fields = @model.fields
61
+ end
62
+
63
+ def handle_has_one
64
+ has_ones = @fields.select{|f| f.is_a? Administer::Fields::HasOne }
65
+ @model_params = params[model_class.model_name.underscore]
66
+ has_ones.each do |o|
67
+ if @model_params[o.foreign_key]
68
+ has_one_id = @model_params.delete(o.foreign_key)
69
+ if has_one_id.present?
70
+ @object.send((o.name.to_s+"=").to_sym, o.association_class.find(has_one_id))
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,5 +1,5 @@
1
1
  module Administer::DashboardHelper
2
2
  def administer_model_names
3
- Administer::Model.all.collect { |m| m.model_name }
3
+ Administer::Model.all.collect { |m| m.entity.model_name }
4
4
  end
5
5
  end
@@ -0,0 +1,2 @@
1
+ module Administer::EntitiesHelper
2
+ end
@@ -4,4 +4,4 @@
4
4
  Models:
5
5
  %ul.administer_model_list
6
6
  - administer_model_names.each do |model_name|
7
- %li= link_to(model_name.human.pluralize, administer_models_path(:model_name => model_name))
7
+ %li= link_to(model_name.human.pluralize, administer_entities_path(:model_name => model_name))
@@ -0,0 +1,9 @@
1
+ - fields.each do |field|
2
+ %p
3
+ = render field.partial, :field => field, :f => f, :form_object => object
4
+ - if errors = object.errors[field.name]
5
+ %span.errors
6
+ - errors.each do |error|
7
+ = error
8
+ - unless errors.last == error
9
+ %br
@@ -0,0 +1,9 @@
1
+ #edit
2
+ %ul.actions
3
+ %li= link_to('back', administer_entities_path(:model_name => model_class.model_name))
4
+ %h1
5
+ Edit
6
+ = model_class.model_name.human
7
+ = form_for @object, :url => administer_entity_path(@object, :model_name => model_class.model_name) do |f|
8
+ = render 'form', :fields => @fields, :f => f, :object => @object
9
+ = f.submit "Update #{model_class.model_name}"
@@ -0,0 +1,21 @@
1
+ #index
2
+ %ul.actions
3
+ %li= link_to('back', administer_dashboard_index_path)
4
+ %li= link_to("New #{model_class.model_name.human}", new_administer_entity_path(:model_name => model_class.model_name))
5
+ %h1= model_class.model_name.human.pluralize
6
+ %table.items_list
7
+ %thead
8
+ %tr
9
+ - model_class.column_names.each do |column_name|
10
+ %th= column_name
11
+ %th Actions
12
+
13
+ %tbody
14
+ - @collection.each do |object|
15
+ %tr{:class => cycle('odd', 'even')}
16
+ - model_class.column_names.each do |column_name|
17
+ %td= object.send(column_name).to_s
18
+ %td
19
+ %ul.actions
20
+ %li= link_to("Edit", edit_administer_entity_path(object, :model_name => model_class.model_name))
21
+ %li= button_to("Delete", administer_entity_path(object, :model_name => model_class.model_name), :method => :delete)
@@ -0,0 +1,9 @@
1
+ #new
2
+ %ul.actions
3
+ %li= link_to('back', administer_entities_path(:model_name => model_class.model_name))
4
+ %h1
5
+ New
6
+ = model_class.model_name.human
7
+ = form_for @object, :url => administer_entities_path(:model_name => model_class.model_name) do |f|
8
+ = render 'form', :fields => @fields, :f => f, :object => @object
9
+ = f.submit "Create #{model_class.model_name}"
@@ -0,0 +1,2 @@
1
+ = f.label field.primary_key, field.name.to_s.humanize
2
+ = f.select field.primary_key, field.collection.map { |object| [field.display_object(object), object.id] }
@@ -0,0 +1,2 @@
1
+ = f.label field.name
2
+ = f.date_select field.name
@@ -0,0 +1,4 @@
1
+ %h2= field.name.to_s.humanize
2
+ - field.collection.each do |entity|
3
+ = check_box_tag field.check_box_name, entity.id, field.checked?(@object, entity), :id => field.dom_id(entity)
4
+ = label_tag field.dom_id(entity), field.display_object(entity)
@@ -0,0 +1,2 @@
1
+ = f.label field.dom_id, field.name.to_s.humanize
2
+ = select_tag field.select_name, options_for_select(field.options, form_object.send(field.name).try(:id)), {:id => field.dom_id}
@@ -0,0 +1,2 @@
1
+ = f.label field.name
2
+ = f.text_area field.name
@@ -0,0 +1,2 @@
1
+ = f.label field.name
2
+ = f.text_field field.name
@@ -0,0 +1,6 @@
1
+ - if object.errors.any?
2
+ #errorExplanation
3
+ %h2= "#{pluralize(object.errors.count, 'error')} prohibited this #{object.class.model_name} from being saved:"
4
+ %ul
5
+ - object.errors.full_messages.each do |msg|
6
+ %li= msg
@@ -0,0 +1,21 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title Administer
5
+ = stylesheet_link_tag :all
6
+ = javascript_include_tag :defaults
7
+ = csrf_meta_tag
8
+ %style{:type => "text/css", :media => "screen"}
9
+ :css
10
+ #
11
+ %body
12
+ #adminiser
13
+ .header
14
+ %ul.navigation
15
+ %li
16
+ = link_to "Go to application", root_path
17
+ .flash#error
18
+ = flash[:error]
19
+ .flash#notice
20
+ = flash[:notice]
21
+ = yield
@@ -1,8 +1,8 @@
1
- Rails.application.routes.draw do |map|
1
+ Rails.application.routes.draw do
2
2
  namespace :administer do
3
- resources :dashboard
4
- resources :models
3
+ resources :dashboard, :only => :index
4
+ resources :entities
5
5
  end
6
-
6
+
7
7
  match 'administer', :to => 'administer/dashboard#index'
8
8
  end
@@ -1,2 +1,3 @@
1
1
  require 'administer/engine'
2
2
  require 'administer/model'
3
+ require 'administer/config'
@@ -0,0 +1,22 @@
1
+ module Administer::Fields
2
+ FieldBuilder.register_class ActiveRecord::ConnectionAdapters::Column do |column|
3
+ case column.type
4
+ when :text
5
+ TextArea.new(column.name)
6
+ when :date
7
+ DateSelect.new(column.name)
8
+ else
9
+ TextField.new(column.name)
10
+ end
11
+ end
12
+ FieldBuilder.register_class ActiveRecord::Reflection::AssociationReflection do |reflection|
13
+ case reflection.macro
14
+ when :belongs_to
15
+ BelongsTo.new(reflection.name, reflection.primary_key_name, reflection.klass, reflection.active_record)
16
+ when :has_many
17
+ HasMany.new(reflection.name, reflection.klass, reflection.active_record)
18
+ when :has_one
19
+ HasOne.new(reflection.name, reflection.association_foreign_key, reflection.klass, reflection.active_record)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ Dir[ File.expand_path("config/**/*.rb", File.dirname(__FILE__))].each { |f| require f }
2
+
3
+ module Administer
4
+ class Config
5
+ class << self
6
+ def configure(&block)
7
+ @@config = Config.new(&block)
8
+ end
9
+
10
+ def for(klass)
11
+ @@config.for(klass) if @@config
12
+ end
13
+
14
+ def controller
15
+ @@config.get_instance_variable(:@controller_config)
16
+ end
17
+ end
18
+
19
+ def initialize(&block)
20
+ @model_configs = {}
21
+ self.instance_eval &block
22
+ end
23
+
24
+ def for(klass)
25
+ @model_configs[klass.to_s.to_sym]
26
+ end
27
+
28
+ private
29
+ def model(klass, &block)
30
+ @model_configs[klass.to_s.to_sym] = ModelConfigBuilder.new(&block).build
31
+ end
32
+
33
+ def controller(&block)
34
+ @controller_config = ControllerConfigBuilder.new(&block).build
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ module Administer
2
+ class Config
3
+ class ControllerConfigBuilder
4
+ def initialize(&block)
5
+ @controller_config = ControllerConfig.new
6
+ self.instance_eval(&block)
7
+ end
8
+
9
+ def build
10
+ @controller_config
11
+ end
12
+
13
+ private
14
+ def before_filter(method_name, &block)
15
+ raise "Provide method_name or block and not both" unless [method_name, block].select(&:present?).count == 1
16
+ @controller_config.before_filter = method_name || block
17
+ end
18
+ end
19
+
20
+ class ControllerConfig
21
+ attr_accessor :before_filter
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ module Administer
2
+ class Config
3
+ class ModelConfigBuilder
4
+ def initialize(&block)
5
+ @model_config = ModelConfig.new
6
+ self.instance_eval(&block)
7
+ end
8
+
9
+ def display_name(method_name = nil, &block)
10
+ raise "Provide method_name or block and not both" unless [method_name, block].select(&:present?).count == 1
11
+ @model_config.display_name = method_name || block
12
+ end
13
+
14
+ def build
15
+ @model_config
16
+ end
17
+ end
18
+
19
+ class ModelConfig
20
+ attr_accessor :display_name
21
+ end
22
+ end
23
+ end
@@ -1,7 +1,12 @@
1
1
  require "administer"
2
2
  require "rails"
3
+ require "haml"
4
+ require "superclass_hash"
3
5
 
4
6
  module Administer
5
7
  class Engine < Rails::Engine
8
+ initializer "administer.initiailze_orm", :after => :finisher_hook do
9
+ require File.expand_path("active_record", File.dirname(__FILE__))
10
+ end
6
11
  end
7
12
  end
@@ -0,0 +1,34 @@
1
+ require File.expand_path("fields/base", File.dirname(__FILE__))
2
+ require File.expand_path("fields/association", File.dirname(__FILE__))
3
+ Dir[ File.expand_path("fields/**/*.rb", File.dirname(__FILE__))].each { |f| require f }
4
+ module Administer
5
+ module Fields
6
+ def fields
7
+ all_fields = get_fields_list
8
+
9
+ visible_fields = all_fields.delete_if{ |field| ["id", "created_at", "updated_at"].any?{ |a| a == field.name } }
10
+ FieldBuilder.new.build_fields_for(visible_fields)
11
+ end
12
+
13
+ private
14
+ def get_fields_list
15
+ fields = without_belongs_to_keys(@entity.columns)
16
+ fields + associations
17
+ end
18
+
19
+ def columns
20
+ @entity.columns
21
+ end
22
+
23
+ def without_belongs_to_keys(columns)
24
+ belongs_to_keys = associations(:belongs_to).map do |assoc|
25
+ assoc.primary_key_name
26
+ end
27
+ columns.reject { |column| belongs_to_keys.include?(column.name) }
28
+ end
29
+
30
+ def associations(type = nil)
31
+ @entity.reflect_on_all_associations(type)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ module Administer
2
+ module Fields
3
+ class Association < Administer::Fields::Base
4
+ attr_reader :association_class, :parent_class, :association_config
5
+ def initialize(name, association_class, parent)
6
+ super(name)
7
+ @association_class = association_class
8
+ @parent_class = parent
9
+ @association_model = Administer::Model.for(@association_class)
10
+ end
11
+
12
+ def collection
13
+ @association_class.all
14
+ end
15
+
16
+ def display_object(object)
17
+ @association_model.display_name(object)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Administer
2
+ module Fields
3
+ class Base
4
+ attr_reader :name
5
+ def initialize(name)
6
+ @name = name
7
+ end
8
+
9
+ def partial
10
+ partial_name = self.class.to_s.underscore.split("/")[-1]
11
+ "administer/fields/#{partial_name}"
12
+ end
13
+ end
14
+ end
15
+ end