Learning Rails 24 Decorators Pattern


```:bash
vi app/models/user.rb
```

Add this line

```ruby:user.rb
def past_5_days?
  created_at >= 5.days.ago
end
```

current user.rb

```ruby:user.rb
class User < ActiveRecord::Base
  has_many :reviews
  has_many :user_items
  has_many :items, through: :user_items
 
  validates :name,
            presence: true,
            length: {minimum: 3}
 
  def past_5_days?
    created_at >= 5.days.ago
  end
end
```

```:bash
vi app/views/users/index.html.erb
```

Add this line

```ruby:index.html.erb
<% if user.past_5_days? %>
<% end %>
```

current index.html.erb

```ruby:index.html.erb
<h1>Users</h1>
 
<ul>
  <% @users.each do |user| %>
    <li>
      <% if user.past_5_days? %>
        <%= link_to user.name, user_path(user.id) %>:<%= user.approved%>;
        <%= link_to 'edit', edit_user_path(user.id) %>;
        <%= link_to 'delete', user_path(user.id), method: :delete, data: {confirm: "Are you sure?"} %>
        <%= link_to 'suspend', suspend_user_path(user.id), data: {confirm: "suspend?"} %>
        <%= link_to 'permit', permit_user_path(user.id), data: {confirm: "permit?"} %>
      <% end %>
    </li>
  <% end %>
</ul>
 
<p><%= link_to "Add New", new_user_path %></p>
```

past_5_days method is used only view file.
It it right?

####We will refactor it

```:bash
mkdir app/decorators
```

```:bash
vi app/decorators/user_decorator.rb
```

```ruby:user_decorator.rb
class UserDecorator
  attr_reader :user
 
  def initialize(user)
    @user = user
  end
 
  def past_5_days?
    user.created_at >= 5.days.ago
  end
end
```

Delete past_5days?
current user.rb

```ruby:user.rb
class User < ActiveRecord::Base
  has_many :reviews
  has_many :user_items
  has_many :items, through: :user_items
 
  validates :name,
            presence: true,
            length: {minimum: 3}
end
```

```:bash
vi app/views/users/index.html.erb
```

```ruby:index.html.erb
<% if UserDecorator.new(user).past_5_days? %>
<% end %>
```

current index.html.erb

```ruby:index.html.erb
<h1>Users</h1>
 
<ul>
  <% @users.each do |user| %>
    <li>
      <% if UserDecorator.new(user).past_5_days? %>
        <%= link_to user.name, user_path(user.id) %>:<%= user.approved %>;
        <%= link_to 'edit', edit_user_path(user.id) %>;
        <%= link_to 'delete', user_path(user.id), method: :delete, data: {confirm: "Are you sure?"} %>
        <%= link_to 'suspend', suspend_user_path(user.id), data: {confirm: "suspend?"} %>
        <%= link_to 'permit', permit_user_path(user.id), data: {confirm: "permit?"} %>
      <% end %>
    </li>
  <% end %>
</ul>
 
<p><%= link_to "Add New", new_user_path %></p>
```

We will change show method in users_controller

```:bash
vi app/controllers/users_controller.rb
```

```ruby:users_controller.rb
require 'user_decorator'
```

```ruby:users_controller.rb
def show
  @user_decorator = UserDecorator.new(@user)
  @items = Item.all.pluck(:name, :id)
end
```

```:bash
vi app/views/users/show.html.erb
```

```ruby:show.html.erb
<% if @user_decorator.past_5_days? %>
  <%= @user_decorator.name %>:<%= @user_decorator.approved %>
<% end %>
```

![スクリーンショット 2016-05-03 22.54.14.png](https://qiita-image-store.s3.amazonaws.com/0/39073/f673092d-6cc4-b813-ec4e-8d431906eed2.png "スクリーンショット 2016-05-03 22.54.14.png")

Add this line

```ruby:user_decorator.rb
def method_missing(method_name, *args, &block)
  user.send(method_name, *args, &block)
end
```

```:bash
ctrl + c
```

```:bash
rails c
```

We need to refactor Decorator

```ruby:console
rails c
```

```ruby:console
require '/srv/www/learning/app/decorators/user_decorator'
```

```ruby:console
user_decorator = UserDecorator.new User.first
```

```ruby:console
user_decorator.respond_to?(:name)
```

result is false. However result should be true.

![スクリーンショット 2016-05-03 22.57.55.png](https://qiita-image-store.s3.amazonaws.com/0/39073/87f5d3cd-4f77-e3b2-c502-e25375f93a58.png "スクリーンショット 2016-05-03 22.57.55.png")

```:bash
vi app/decorators/user_decorator.rb
```

```ruby:user_decorator.rb
def respond_to_missing?(method_name, include_private = false)
  user.respond_to?(method_name, include_private) || super
end
```

```ruby:console
user_decorator.respond_to?(:name)
```

######result is true now

![スクリーンショット 2016-05-03 23.00.17.png](https://qiita-image-store.s3.amazonaws.com/0/39073/357803f1-1a69-10bc-6ddd-cb356946ccf3.png "スクリーンショット 2016-05-03 23.00.17.png")