使用 Draper 装饰器的未定义方法 link_to_edit

Undefined method link_to_edit using Draper decorator

我有一个 User 和 Post 模型,它们以经典方式相互关联 -- User has_many :postsPost belongs_to :user。在我的 users#show 中,我显示了用户的个人资料,我还列出了他所做的所有 post。另外,我希望有链接以恭敬地编辑和删除每个 post。所以,我弥补了这个:

<% @user.posts.each do |post| %>
  <h1><%= link_to post.title, post_path(post) %></h1>
  <% if @user == current_user %>
      <%= link_to 'Edit', edit_post_path(post) %>
      <%= link_to 'Delete', post_path(post), method: :delete %>
  <% end %>
<% end %>

但是肯定会把这个逻辑放在视图中导致一团糟,所以我决定使用 Draper 并为此编写装饰器。由于我们要检查 posts#editposts#delete 方法的权限,我想出了一个 Post 模型的装饰器并尝试在 PostsController 中使用它。开始了:

class PostDecorator << Draper::Decorator
  delegate_all

  def link_to_edit
    if object.user == current_user
      h.link_to 'Edit', h.edit_post_path(object)
    end
  end

  def link_to_delete
    if object.user == current.user
      h.link_to 'Delete', h.post_path(object), method: :delete
    end
  end   
end

然后,在我的 PostsController:

# ... class definition
before_action :set_post, only: [:show, :edit, :update, :destroy]

# ... other controller methods
def edit; end

def update
  if @post.update(post_params)
    @post.save
    redirect_to post_path(@post)
  else
    render 'edit'
  end
end

def destroy
  @post.destroy
  redirect_to feed_path
end

private

# Using FriendlyId gem to have neat slugs
def set_post
  @post = Post.friendly.find(params[:id]).decorate
end

但每次我尝试使用我的新助手 <%= post.link_to_delete %><%= post.link_to_edit %> 来呈现他的 post 列表的用户个人资料时,而不是那种条件混乱,它只是 returns 我出现以下错误:

我做错了什么?

您可能同时想到了这一点,但这是其他人的答案:您在控制器中调用 @post = ....decorate,但在视图中使用 @user.posts.each { |post| ... }。提供给该块的对象没有装饰。只有 @post 是。

在您看来,您应该做 @user.posts.each { |raw_post| post = raw_post.decorate } 之类的事情。显然,用 ERB 语法。或者 @user.decorated_posts.each ... 其中

class User < ActiveRecord::Base
  ...
  def decorated_posts
    # this will load every post associated with the user.
    # if there are a lot of them you might want to only load a limited scope of them
    posts.map(&:decorate)
  end
  ...
end