La classe de Validation échouée doit exister

j'ai eu (des heures) des problèmes avec les associations dans les Rails. J'ai trouvé beaucoup de problèmes similaires, mais je ne pouvais pas demander à 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

Utilisateurs Contrôleur:

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):

Eh bien, le problème est, les attributs du modèle de L'utilisateur qui ne sont pas FK ils sont accepter par l'Utilisateur.save method, et les attributs FK comme citys_id ne le sont pas. Ensuite, il me donne message d'erreur dans le navigateur disant que "Validation ville échoué doit exister".

Merci

27
demandé sur Pedro Gabriel Lima 2016-08-16 23:13:23

6 réponses

Essayez le code suivant:

belongs_to :city, optional: true

Selon nouveau docs:

4.1.2.11 :facultatif

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

59
répondu Igor_Marques 2016-08-17 00:53:02

cela arrive un peu tard, mais c'est comme ça qu'on éteint ça par défaut dans les rails 5:

config/initializers / new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false

j'espère que cela aide!

5
répondu Jeremie 2018-07-09 01:41:35

vous devez ajouter ce qui suit à la fin de l'instruction belongs_to relationship:

optional: true

il est possible de régler cela à un niveau global pour que cela fonctionne de la même manière que les anciennes versions de rails, mais je recommande de prendre le temps de l'ajouter manuellement aux relations qui en ont vraiment besoin car cela causera moins de douleur à l'avenir.

3
répondu David Kane 2017-08-14 13:20:30

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 à true, alors la présence de l'objet associé ne sera pas validée. Par défaut, cette option est définie à false.

parce que vous faites encore 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 user_params méthode:

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 il fonctionne dans une autre mine de projet. J'espère que cela peut aider les autres!

1
répondu Pedro Gabriel Lima 2017-04-05 12:27:30
belongs_to :city, required: false
1
répondu Alex P 2017-07-25 10:41:02

Rails 5

si vous avez une relation belongs_to avec: parent, alors vous devez passer un objet parent existant ou en créer un nouveau puis l'affecter à un objet children.

0
répondu RickS 2018-04-18 15:38:19