使用 Draper 装饰器的未定义方法 link_to_edit
Undefined method link_to_edit using Draper decorator
我有一个 User 和 Post 模型,它们以经典方式相互关联 -- User has_many :posts
和 Post 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#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 %>
来呈现他的 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
我有一个 User 和 Post 模型,它们以经典方式相互关联 -- User has_many :posts
和 Post 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#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 %>
来呈现他的 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