Skip to content

Commit

Permalink
4.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tian-im committed Apr 22, 2016
1 parent 93405b7 commit 5e86d0e
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 111 deletions.
30 changes: 20 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
# v4.0.0.rc
# v4.0.0

1. Used Rails cache for caching subclasses
2. Added support for CanCanCan (authorization)
3. Added support for all Postgres types
4. Added support for sorting
5. Added model servicer to take away the responsibilities (collection/find/initialize) for model decorator and extract all actions for resource controller
1. Used model class to dispatch requests to controllers
2. Fixed sorting / remove link for custom fields on index page table headers
3. Added types email and color for index/show/form
4. Ensure all hashes used for fields is instance of HashWithIndifferentAccess

# WIP Feature list
# WIP Wish list

- Add lint check
- Change to use a mode so that multiple mode (active_record/mongoid/etc.) can be used at the same time
- Ensure to support mysql and sqlite
- Support for Single Table Inheritance (STI)
- Improve colon search (use papertrail) (maybe..)
- Data Audit (use papertrail) (maybe..)
- Improve colon search (maybe..)
- Data audit (use papertrail) (maybe..)
- Data export (maybe..)
- Batch data action (maybe..)

# Known issues

- Missing assets for kaminari and bootstrap-sass if kaminari and bootstrap-sass are not in the `Gemfile`
N/A

# History:
## v4.0.0.rc

1. Used Rails cache for caching subclasses
2. Added support for CanCanCan (authorization)
3. Added support for all Postgres types
4. Added support for sorting
5. Added model servicer to take away the responsibilities (collection/find/initialize) for model decorator and extract all actions for resource controller

## v0.0.6

1. Resolved Autoload issue
Expand Down
212 changes: 137 additions & 75 deletions CUSTOMIZATION.md
Original file line number Diff line number Diff line change
@@ -1,124 +1,186 @@
# Customization

This engine allows us to do further development in Rails way from the following sections.
Customization can be done in the following sections, and all examples will be based on Product model:

First of all, let, if you have a model call `Product` and it has the following columns:
- [Controller](#controller)
- [Decorator](#decorator)
- [Servicer](#servicer)
- [View](#view)

- sku:string
- name:string
- category_id:integer
- description:text
- stock:integer
- price:float
- featured:boolean
- available_to_date:date
- available_to_time:time
- published_at:datetime
> NOTE: model class is the only thing carried through a complete request.
And it has model declaration as below:
## Controller

In order to customize a controller action, controller should inherit from `Wallaby::ResourcesController` as below, then we could override the general RESTful actions (index/show/new/create/edit/update/destroy):

```ruby
class Product < ActiveRecord::Base
has_one :product_detail
has_one :picture, as: :imageable
has_many :order_items, class_name: Order::Item.name
has_many :orders, through: :order_items
belongs_to :category
has_and_belongs_to_many :tags

validates_presence_of :name, :sku
#!app/controllers/products_controller.rb
class ProductsController < Wallaby::ResourcesController
def index; super; end
def show; super; end
def new; super; end

# @example override create action
def create
flash[:notice] = 'Create product is in progress'
super
end

def edit; super; end
def update; super; end
def destroy; super; end
end
```

## Configuration

This engine by default uses ActiveRecord adaptor, you could change this to other adaptor (e.g. Mongo / HER adaptor) as below:
If you have already declared a ProductsController for other purpose, you could use other controller name and specify the model class.

```ruby
# config/initializers/wallaby.rb
Wallaby.config do |config|
config.adaptor = Wallaby::SomeOtherAdaptor
#!app/controllers/admin/products_controller.rb
class Admin::ProductsController < Wallaby::ResourcesController
def self.model_class
Product
end
end
```

By default, there is no authentication, and you need to do the following config if you need one:
## Decorator

If we need to change what fields to show, or update the metadata information of a field, we consider to use decorator.

```ruby
# config/initializers/wallaby.rb
Wallaby.config do |config|
config.security.authenticate do
# you could use any controller methods here
authenticate_or_request_with_http_basic do |username, password|
username == 'too_simple' && password == 'too_naive'
end
end

config.security.current_user do
# you could use any controller methods here
Class.new do
def email
'user@example.com'
end
end.new
#!app/decorators/product_decorator.rb

# NOTE: Product in ProductDecorator must be singular
class ProductDecorator < Wallaby::ResourceDecorator
# example of metadata:
# {
# column_name: {
# type: string,
# label: 'Column Name',
# name: 'column_name'
# }
# }
self.index_fields # metadata for index page
self.show_fields # metadata for show page
self.form_fields # metadata for new/create/edit/update page

# example of field_names:
# [ 'id', 'column1', ..., 'created_at', 'updated_at' ]
self.index_field_names # array of column names to display on index page
self.show_field_names # array of column names to display on show page
self.form_field_names # array of column names to display on form page

# examples
self.index_fields[:email][:type] = 'email'
self.index_fields[:full_product_name] = { type: 'string', label: 'Product Name' }
self.index_field_names << 'full_product_name'

def full_product_name
[ product_name, sku ].compact.join ' - '
end
end
```

You could hide some models using configuration as below:
Similarly, if ProductDecorator is taken, we could other name and specify the model class.

```ruby
# config/initializers/wallaby.rb
Wallaby.config do |config|
config.models.exclude ProductDetail, Order, Order::Item
#!app/decorators/admin/product_decorator.rb
class Admin::ProductDecorator < Wallaby::ResourceDecorator
def self.model_class
Product
end
end
```

## Controller
## Servicer

You could modify the logics for Post model by defining a controller as below:
If any actions need to be carried out in the persistence layer, we use a servicer (service object):

```ruby
class PostsController < Wallaby::ResourceController
def create
# do something else
super
#!app/servicers/product_servicer.rb
class ProductServicer < Wallaby::ModelServicer
# @return collection of resources
def collection(params, ability); super; end

# @return resource
def new(params); super; end

# @return resource
def find(id, params); super; end

# @example override create method
# @return [ resource, boolean ]
def create(params, ability)
product, success = super
publish_and_index product
[ product, success ]
end

# @return [ resource, boolean ]
def update(resource, params, ability); super; end

# @return boolean
def destroy(resource, params); super; end
end
```
# OR any controller name you want, but specifying the `model_class`
class Admin::CustomPostsController < Wallaby::ResourceController
def self.model_class
Post
end
Similarly, if there is name conflict, just use other name and specify the model class.
def create
# do something else
super
```ruby
#!app/servicers/admin/product_servicer.rb
class Admin::ProductServicer < Wallaby::ModelServicer
def self.model_class
Product
end
end
```
## Decorator
## View
It is easy to customize how a field should be rendered. In the following example, we will change product description to be rendered using markdown on index page:
Similar to the controller above, you could use two ways to define a decorator.
Having a decorator, you could then modify what fields to use for views index/show/form
First of all, we need to update the type in decorator:
```ruby
class PostDecorator < ResourceDecorator
index_field_names.delete 'body'
show_fields['body'][:type] = 'markdown'
form_fields['body'][:label] = 'Content'
#!app/decorators/product_decorator.rb
class ProductDecorator < Wallaby::ResourceDecorator
self.index_fields[:description][:type] = 'markdown'
end
```
## View
Then we need to add a partial for it. The partial can be either created under
You could easily define any field view for any custom type (e.g. markdown) for Post by defining a partial under `app/views/posts/index/_markdown`
```
#!app/views/products/index/_markdown.html.erb
```
If it's product specific. Or
```
#!app/views/wallaby/resources/index/_markdown.html.erb
```
If it applies to all markdown fields.
```erb
<%# The local variables in the partial are `value` %>
<%= markdown.render value %>
<%= markdown.render value %>
```
If you want to make it available for other models, you could move it to `app/views/resources/index/_markdown`
### Index / show partials
For index and show partial, we will have access to the following variables:
- `object`: the resource object
- `field_name`: current field name
- `value`: current value
- `metadata`: metadata for current field
### Form partials
For index and show partial, we will have access to the following variables:
- `form`: the instance of Wallaby::FormBuilder providing additional helper methods for error class and error messages
- `object`: the resource object
- `field_name`: current field name
- `value`: current value
- `metadata`: metadata for current field
13 changes: 6 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
PATH
remote: .
specs:
wallaby (4.0.0.rc)
wallaby (4.0.0)
bootstrap-sass
bootstrap3-datetimepicker-rails
cancancan
codemirror-rails
devise
devise (>= 3.5, < 4.0)
jquery-minicolors-rails
jquery-rails
kaminari
momentjs-rails
rails (>= 4.0)
rails (>= 4.0, < 5.0)
rails-bootstrap-markdown
redcarpet
sass-rails
sprockets-rails
summernote-rails
Expand Down Expand Up @@ -79,11 +78,12 @@ GEM
concurrent-ruby (1.0.1)
database_cleaner (1.4.0)
debug_inspector (0.0.2)
devise (4.0.0)
devise (3.5.6)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.1)
railties (>= 3.2.6, < 5)
responders
thread_safe (~> 0.1)
warden (~> 1.2.3)
diff-lcs (1.2.5)
erubis (2.7.0)
Expand Down Expand Up @@ -154,7 +154,6 @@ GEM
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (11.1.1)
redcarpet (3.3.4)
responders (2.1.2)
railties (>= 4.2.0, < 5.1)
rspec-core (3.4.4)
Expand Down
Loading

0 comments on commit 5e86d0e

Please sign in to comment.