Неопределенный метод link_to_edit с использованием декоратора Draper

У меня есть модели 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 %> вместо этого условного беспорядка он просто возвращает мне следующую ошибку:

ошибка

Что я делаю неправильно?

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
Другие вопросы по тегам