-
Notifications
You must be signed in to change notification settings - Fork 0
Backend Training: Decorator
🔖 : draper
By now we can display posts and faqs data from the database. The only issue now is that some of the contexts are not formatted correctly. For example, the date format is different from the ones showing on the mockup.
So let's add some decorators to fix the issues.
# app/decorators/post_decorator.rb
# Decorates Post
class PostDecorator < Draper::Decorator
delegate_all
def published_date
object.published_date.strftime('%B %d, %Y')
end
def published_date_short
object.published_date.strftime('%b %d, %Y')
end
def content_short
return if content.blank?
truncate(strip_tags(content), length: 250)
end
end
Call decorator from controller
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
......
def index
@posts = Post.published
filter_posts
@posts = @posts.by_published_date.
paginate(page: params[:page], per_page: 9).
decorate
end
......
end
Refresh the browser Command ⌘+r, and oops. Seems like will_paginate is not working well with decorators.
Let's fix this by adding a file app/decorators/paginating_decorator.rb
# app/decorators/paginating_decorator.rb
# Pagination Patch
class PaginatingDecorator < Draper::CollectionDecorator
# support for will_paginate
delegate :current_page, :per_page, :offset, :total_entries, :total_pages
end
And add another file called app/decorators/application_decorator.rb
# app/decorators/application_decorator.rb
# Dercorator Base
class ApplicationDecorator < Draper::Decorator
include Draper::LazyHelpers
delegate_all
def self.collection_decorator_class
PaginatingDecorator
end
end
Now change app/decorators/post_decorator.rb
to inherit from ApplicationDecorator
# app/decorators/post_decorator.rb
# Decorates Post
class PostDecorator < ApplicationDecorator
Refresh the browser Command ⌘+r, and the page should render now.
Let's apply decorator in the views by calling the methods we created previously
.col-sm-6.col-md-4
.thumbnail
= holder_tag '300x150', 'Sample Image', '', class: 'img-responsive'
.caption
h4= link_to post.title, post
p.text-muted= post.category_list
br/
p= post.content_short
br/
p.text-muted= post.published_date_short
Now your post should look like
Let's add decorator to show page as well.
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
.....
def show
@post = Post.published.
friendly.find(params[:id]).decorate
end
......
Go to show page and now the show page is working as expected.
Let's add a decorator for faq as well
# app/decorators/faq_decorator.rb
# Decorates Faq
class FaqDecorator < ApplicationDecorator
# app/controllers/faqs_controller.rb
class FaqsController < ApplicationController
def index
@faqs = Faq.by_position.decorate
end
end
One last thing, remember we also have posts inside home#index so let's fix them as well.
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
@posts = Post.published.by_published_date.
limit(3).decorate
@faqs = Faq.by_position.decorate
end
......
end
Refresh the browser Command ⌘+r, and they should all be working correctly now.
Let's commit your changes before moving on to the next step.
$ git add -A
$ git commit -m 'Post & Faq Decorators'