2012-12-18 1 views
1

Supposons que vous ayez un Question et un Answer et que les nouvelles réponses proviennent de la page questions#show (comme StackoverFlow).Modèle pour éviter le couplage entre les actions de contrôleur des contrôleurs parent et enfant

À moins que le questions#show et les actions answers#create charger des données identiques, le answers#create jetteront une exception (généralement pas de méthode de la classe nulle) s'il y a une erreur de validation d'une nouvelle réponse. Ce n'est pas un problème majeur, mais lorsque vous ajoutez des filtres et d'autres types de données, le code commence à sentir, et vous obtenez un couplage étroit entre les deux actions. Changer une exige de changer l'autre - quelque chose facile à oublier.

Je me demande ce que les développeurs expérimentés de Rails font, le cas échéant, pour éviter ce couplage?

# Assume Discussion = Question, and Response = Answer 
    # Discussions#show 
    def show 
    @discussion = Discussion.find(params[:id]) # The question 
    @responses = @discussion.responses.includes(:author) # Existing answers 
    @response = @discussion.responses.build # New answer object for the form 
    order = 'users.role' 
    if params[:filter].present? 
     order = case params[:filter] 
     when 'new' 
     then 'responses.created_at DESC' 
     end 
    end 
    @responses = @responses.order(order) 
    end 

Maintenant, regardons l'action responses#create, qui doit charger les mêmes données pour render au travail (si la validation échoue):

# Responses#create 
    def create 
    # @discussion is loaded using a before filter 
    @response = @discussion.responses.build(params[:response]) 
    @response.author = current_user 
    @responses = @discussion.responses.includes(:author) 
    order = 'users.role' 
    if params[:filter].present? 
     order = case params[:filter] 
     when 'new' 
     then 'responses.created_at DESC' 
     end 
    end 
    @responses = @responses.order(order) 
    respond_to do |format| 
     if @response.save 
     format.html { redirect_to @discussion } 
     format.js 
     else 
     format.html { render 'discussions/show' } # fails if discussions#show and responses#new do not load the same data. 
     end 
    end 
    end 

Répondre

1

Il semble que votre problème est que vous avez très serré le couplage entre des actions de contrôleurs sans rapport, puisque les réponses # create essayent aussi d'être un # de discussion.

Une option consiste à rediriger vers @discussion sur les erreurs de validation ainsi que le succès, et transmettre les paramètres de réponse soumis à la redirection. Ensuite, vous pouvez gérer le cas "spécial" qu'il y a des données de réponse dans l'action de show question.

Questions connexes