administer 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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