2017-07-17 5 views
2

J'ai une table TranslationsUser et une table FavoriteTranslation. Je souhaite que TranslationsUser n'ait qu'une seule traduction préférée, mais je ne souhaite pas utiliser de validations car je souhaite que mon contrôleur remplace une traduction favorite si elle existe déjà. Au lieu de cela, j'ai créé une fonction validate_uniqueness.Rails/RoR - NoMethodError (méthode non définie `destroy 'pour nil: NilClass)

Lorsque je tente de remplacer un TranslationsUser avec une nouvelle traduction préférée, je reçois l'erreur suivante dans mon terminal: NoMethodError (undefined method `destroy' for nil:NilClass):

Je pense que le problème peut être le before action :set_favorite_translation puisqu'il définit @favorite_translation

Si alors, comment puis-je supprimer un enregistrement FavoriteTranslation spécifique:

Si non, aidez-moi à comprendre le problème! Merci beaucoup.


before_action :set_favorite_translation, only: [:show, :edit, :update, :destroy] 


def create 

    transUser = TranslationsUser.find(favorite_translation_params[:translations_user_id]) 


    @favorite_translation = FavoriteTranslation.new(favorite_translation_params) 
    @favorite_translation.user_id = @current_user.id 

    if validate_uniqueness(transUser) == false 
     transUser.favorite_translations.first.destroy 
    end 

    respond_to do |format| 
     if @favorite_translation.save 
     #format.html { redirect_to @favorite_translation, notice: 'Translations users comment was successfully created.' } 
     format.json { head :no_content } 
     else 
     format.html { render :new } 
     format.json { render json: @favorite_translation.errors, status: :unprocessable_entity } 
     end 
    end 

end 

def validate_uniqueness(transUser) 
     if FavoriteTranslation.joins(:translations_user).where('lang_id = ?', transUser.lang_id).where('favorite_translations.user_id = ?', @current_user.id).where('translations_users.translation_id = ?', transUser.translation_id).exists? 
      return false 
     else 
      return true 
     end 
end 

def destroy 
    @favorite_translation.destroy 
    respond_to do |format| 
     format.html { redirect_to favorite_translations_url, notice: 'Translation was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
end 


private 
def set_favorite_translation 
    @favorite_translation = FavoriteTranslation.find(params[:id]) 
end 
+1

Utiliser la relation 'has_one' et par la suite' mettre à jour' l'enregistrement – Nithin

+0

Vous pouvez utiliser 'FavoriteTranslation.where (id: params [: id]). First_or_initialize' ... Mais personnellement, je pense que les validations devraient être au niveau du modèle. Définissez une relation comme citée par @Nithin et utilisez validate_uniqueness_of la validation dans le modèle. Dans le contrôleur, utilisez simplement first_or_initialize ... –

+0

Est-ce que @current_user est un TranslationUtilisateur ou avez-vous aussi un modèle Utilisateur? – stef

Répondre

0

Je suppose que vous y êtes presque. Ajoutez simplement ce qui suit dans la méthode destroy.

def destroy 
    if @favorite_translation 
     @favorite_translation.destroy 
    end 
    respond_to do |format| 
     format.html { redirect_to favorite_translations_url, notice: 'Translation was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
end 

Ce vérifie essentiellement si le favorite_translation est présent, sinon le translationUser ne dispose pas d'un favorite_translation et ainsi permettra au nouveau record à créer.

0

Si vous ne voulez pas de validations, pas de soucis, écrire des associations appropriées vous aidera et DRY votre code ainsi.

Tout d'abord, utilisez has_one :favorite_translation et belongs_to :translations_user associations, puis en vous create l'action ..

def create 

    transUser = TranslationsUser.find(favorite_translation_params[:translations_user_id]) 

    @favTrans = transUser.favorite_translation || transUser.build_favorite_translation 

    @favTrans.assign_attributes(favorite_translation_params) 

    respond_to do |format| 
    if @favTrans.save 
     format.html { redirect_to @favTrans, notice: 'Translations users comment was successfully created.' } 
     format.json { head :no_content } 
    else 
     format.html { render :new } 
     format.json { render json: @favTrans.errors, status: :unprocessable_entity } 
    end 
    end 
end 

Maintenant, vous n'avez pas besoin de destroy dossiers et utiliser has_many relations, créer et mettre à jour sont un peu fusionné ici.

0

J'ai essayé les solutions données, mais j'ai trouvé que ce qui suit a fonctionné. Merci pour votre aide!!!!

def create 
    transUser = TranslationsUser.find(favorite_translation_params[:translations_user_id]) 

    if validate_uniqueness(transUser) == true 
     @favorite_translation = FavoriteTranslation.new(favorite_translation_params) 
     @favorite_translation.user_id = @current_user.id 
    else 
     update 
    end 

    respond_to do |format| 
    if @favorite_translation.save 
     format.json { head :no_content } 
    else 
     format.html { render :new } 
     format.json { render json: @favTrans.errors, status: :unprocessable_entity } 
    end 
    end 
end 


def update 
    transUser = TranslationsUser.find(favorite_translation_params[:translations_user_id]) 
    @favorite_translation = FavoriteTranslation.joins(:translations_user).where('lang_id = ?', transUser.lang_id).where('favorite_translations.user_id = ?', @current_user.id).where('translations_users.translation_id = ?', transUser.translation_id).first 
    @favorite_translation.translations_user_id = favorite_translation_params[:translations_user_id] 
    @favorite_translation.save 

    respond_to do |format| 
     if @favorite_translation.update(favorite_translation_params) 
     'Translations users comment was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render :edit } 
     format.json { render json: @favorite_translation.errors, status: :unprocessable_entity } 
     end 
    end 
end 
0

J'ai enlevé cette ligne

config.action_view.javascript_expansions[:defaults] = %w(jquery.min jquery_ujs) 

de application.rb pour résoudre le problème.