我有一个User和Post模型,它们以经典的方式相互关联 - User has_many :posts
和Post 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#edit
和posts#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 %>
而不是那个有条件的混乱来渲染我的用户个人资料以及他的帖子列表时,它只会返回以下错误:
我做错了什么?
答案 0 :(得分: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