2017-01-26 1 views
0

J'ai des modèles User et Post, qui sont liés les uns aux autres de façon classique - User has_many :posts et Post belongs_to :user. Dans mon users#show, où j'affiche le profil d'un utilisateur, j'ai également une liste de tous les messages qu'il a fait. En outre, je voulais avoir des liens pour modifier et supprimer chaque message avec respect. Alors, je me suis à ceci:Méthode indéfinie link_to_edit en utilisant le décorateur Draper

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

Mais sûrement placer cette logique dans les résultats de la vue dans un désordre, alors j'ai décidé d'utiliser Draper et écrire des décorateurs pour cela. Comme nous allons vérifier les droits pour les méthodes posts#edit et posts#delete, je suis venu avec un décorateur pour Post modèle et j'ai essayé de l'utiliser dans PostsController. Ici, il va:

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 

Puis, dans mon 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 

Mais chaque fois que je tente de rendre mon profil de l'utilisateur avec la liste de ses messages, avec l'utilisation de mes nouvelles aides <%= post.link_to_delete %> et <%= post.link_to_edit %> au lieu de ce désordre sous condition, il me retourne juste l'erreur suivante:

error

Qu'est-ce que est-ce que je fais mal?

Répondre

1

Vous avez probablement compris cela entre-temps, mais voici une réponse pour les autres: Vous appelez @post = ....decorate dans votre contrôleur, mais vous utilisez @user.posts.each { |post| ... } à votre avis. Les objets alimentés à ce bloc ne sont pas décorés. Seul @post est.

À votre avis, vous devriez avoir fait quelque chose comme @user.posts.each { |raw_post| post = raw_post.decorate } et ainsi de suite. Évidemment, avec la syntaxe ERB. Ou @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 
+0

Merci! Votre approche semble beaucoup mieux que la mienne, parce que je viens de retirer le décorateur au modèle '@ user', ce qui ne peut pas être considéré comme la meilleure pratique, je suppose :) – AlexNikolaev94