Je fais de simples sites comme Reddit. J'essaie d'ajouter un bouton aux articles de rapport. Je crée un modèle de rapport , en utilisant button_to J'essaie de publier des données sur le contrôleur de rapport pour le créer mais j'ai reçu NoMethodError dans ReportsController # create fusion de méthode non définie 'pour "post_id": String
model / report.rb
= button_to "Report", reports_path, method: :post, params: {post: post}
report_controller.rb
class ReportsController < ApplicationController
def create
report = Report.new(report_params)
flash[:notice] = if report.save
'Raported'
else
report.errors.full_messages.join('. ')
end
end
def report_params
params.require(:post).merge(reporting_user: current_author.id)
end
end
3 Réponses :
Paramètre ActionController"> require renvoie la valeur de la clé requise dans les paramètres. Il s'agit généralement d'un objet renvoyé depuis un formulaire. Dans cet exemple nécessite code > renverrait {name: "Francesco", age: 22, role: "admin"} et la fusion fonctionnerait.
Votre vue renvoie les paramètres que Rails met en forme dans {post: 'string'} . Nous aurions besoin de voir votre code de vue pour déterminer ce qui doit exactement changer.
Mise à jour: À partir du nouveau code publié, nous pouvons voir que le paramètre renvoyé est "post" => "1" . Normalement, nous attendons un message: {id: 1, ...} .
Mise à jour: le bouton de la vue nécessiterait la mise à jour de la clé params en quelque chose d'ala params: {post: {id: post.id}} < / s> EDIT: J'accepte que params: {report: {post_id: post}} est un meilleur format.
Le problème semble provenir de report_params . Lorsque vous appelez params.require (: post) , il récupère: post de params -> le résultat est une chaîne. Et vous appelez merge sur cette chaîne.
Je recommanderais un changement de vue:
def report_params params.require(:report).permit(:post_id).merge(reporting_user_id: current_author.id) end
puis dans le contrôleur:
= button_to "Report", reports_path, method: :post, params: { report: { post_id: post} }
Notez que j'ai également changé la dénomination selon les conventions: model_id pour id du modèle, modèle ou modèle lui-même.
Quand je passe à params.require (: report) ... j'ai ActiveModel :: ForbiddenAttributesError
Pour commencer, vous voulez utiliser appartient_à et non has_one.
@report = @post.reports.new(report_params) do |r| r.reporting_user = current_user end
Cela place correctement le post_id code> colonne de clé étrangère sur les rapports . L'utilisation de has_one place la colonne fk sur posts , ce qui ne fonctionnera pas.
Et une solution généralement meilleure serait de créer des rapports une ressource imbriquée :
= button_to "Report", post_reports_path(post), method: :post
Cela permet vous simplifiez le bouton pour simplement:
# /config/routes.rb
resources :posts do
resources :reports, only: [:create]
end
# app/controller/reports_controller.rb
class ReportsController
before_action :set_post
# POST /posts/:post_id/reports
def create
@report = @post.reports.new(reporting_user: current_author)
if @report.save
flash[:notice] = 'Reported'
else
flash[:notice] = report.errors.full_messages.join('. ')
end
redirect_to @post
end
private
def set_post
@post = Post.find(params[:post_id])
end
end
Puisque le post_id fait partie du chemin, nous n'avons pas besoin d'envoyer de paramètres supplémentaires. p>
Si vous souhaitez permettre à l'utilisateur de transmettre des informations supplémentaires via un formulaire à l'avenir, une meilleure façon de créer / mettre à jour des ressources avec des paramètres et des données de session est de passer un bloc:
class Report < ApplicationRecord belongs_to :reporting_user, class_name: 'Author' belongs_to :post end
Merci. C'est presque du travail, mais maintenant j'ai l'erreur impossible d'écrire l'attribut inconnu 'reporting_user_id'
Vous devez vous assurer que votre tableau de rapports comporte des colonnes reporting_user_id et post_id . Si ce n'est pas le cas, vous devez les ajouter via une migration.
Pouvez-vous s'il vous plaît ajouter tous les
paramètres? Je pense que le problème sera dans la méthodereport_params, mais j'aimerais être précis.J'ajoute des paramètres entiers dans le premier message