【问题标题】:Undefined method link_to_edit using Draper decorator使用 Draper 装饰器的未定义方法 link_to_edit
【发布时间】:2017-01-26 10:53:41
【问题描述】:

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

<% @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

但每次我尝试使用我的新助手 &lt;%= post.link_to_delete %&gt;&lt;%= post.link_to_edit %&gt; 而不是那种有条件的混乱来呈现我的用户个人资料时,它只会返回以下错误:

我做错了什么?

【问题讨论】:

    标签: ruby-on-rails draper


    【解决方案1】:

    您可能同时想到了这一点,但这是其他人的答案:您在控制器中调用@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
    

    【讨论】:

    • 谢谢!你的方法似乎比我的好得多,因为我刚刚将装饰器移除到 @user 模型,我想这不能被视为最佳实践:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多