web-dev-qa-db-fra.com

La validation a échoué. La classe doit exister

J'ai eu (heures) des problèmes avec les associations dans Rails. J'ai rencontré beaucoup de problèmes similaires, mais je ne pouvais pas postuler pour mon cas:

Classe de la ville:

class City < ApplicationRecord
  has_many :users
end

Classe de l'utilisateur:

class User < ApplicationRecord
  belongs_to :city

  validates :name, presence: true, length: { maximum: 80 }
  validates :city_id, presence: true
end

Contrôleur d'utilisateurs:

def create
    Rails.logger.debug user_params.inspect
    @user = User.new(user_params)
    if @user.save!
      flash[:success] = "Works!"
      redirect_to '/index'
    else
      render 'new'
    end
 end

def user_params
  params.require(:user).permit(:name, :citys_id)
end

Vue des utilisateurs:

<%= form_for(:user, url: '/user/new') do |f| %>
  <%= render 'shared/error_messages' %>

  <%= f.label :name %>
  <%= f.text_field :name %>

  <%= f.label :citys_id, "City" %>
  <select name="city">
    <% @city.all.each do |t| %>
      <option value="<%= t.id %>"><%= t.city %></option>
    <% end %>
  </select>
end

Émigrer:

class CreateUser < ActiveRecord::Migration[5.0]
  def change
    create_table :user do |t|
      t.string :name, limit: 80, null: false
      t.belongs_to :citys, null: false
      t.timestamps
  end
end

Message de la console et du navigateur:

ActiveRecord::RecordInvalid (Validation failed: City must exist):

Le problème est que les attributs du modèle de l'utilisateur qui ne sont pas FK sont acceptés par la méthode User.save et que les attributs FK tels que citys_id ne le sont pas. Ensuite, il me donne un message d'erreur dans le navigateur disant que "La validation a échoué, la ville doit exister".

Merci

34
Pedro Gabriel Lima

Essayez ce qui suit:

belongs_to :city, optional: true

Selon le nouveaux documents :

4.1.2.11: facultatif

Si vous définissez l'option: optional sur true, la présence de l'objet associé ne sera pas validée. Par défaut, cette option est définie sur false.

72
Igor_Marques

Cela arrive un peu tard mais c’est comment désactiver cela par défaut dans Rails 5:

config/initializers/new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false

Si vous ne voulez pas ajouter optional: true à tous vos belongs_to.

J'espère que ça aide!

8
Jeremie

Vous devez ajouter les éléments suivants à la fin de la déclaration de relation appartenance:

optional: true

Il est possible de définir cette option au niveau global de manière à ce qu'elle fonctionne de la même manière que les anciennes versions de Rails, mais je vous conseillerais de prendre le temps de l'ajouter manuellement aux relations qui en ont réellement besoin, car cela entraînerait moins de difficultés pour l'utilisateur. futur.

4
David Kane

Rails 5

Si tu as un belongs_to Relation avec :parent vous devez ensuite transmettre un objet parent existant ou en créer un nouveau, puis l’affecter à l’objet enfants.

2
ricks

J'ai trouvé une solution au problème "La validation a échoué: la classe doit exister" et c'est mieux que d'utiliser:

belongs_to :city, optional: true

4.1.2.11: facultatif

Si vous définissez l'option: optional sur true, la présence de l'objet associé ne sera pas validée. Par défaut, cette option est définie sur false.

car vous faites toujours une validation au niveau de l'application. Je résous le problème en faisant ma propre validation dans la méthode create et en changeant la méthode user_params:

def create

  @city = City.find(params[:city_id])

  Rails.logger.debug user_params.inspect
  @user = User.new(user_params)

  @user.city_id = @city.id

  if @user.save!
    flash[:success] = "Works!"
    redirect_to '/index'
  else
    render 'new'
  end
end

def user_params
  params.require(:user).permit(:name)
end

Je n'ai pas testé ce code, mais cela fonctionne dans un autre projet de mine. J'espère que cela peut aider les autres!

2
belongs_to :city, required: false
1
Purkhalo Alex