Validation failed Class must exist

Ruby on-RailsValidationAssociationsModel AssociationsBelongs To

Ruby on-Rails Problem Overview


I have been (hours) trouble with associations in Rails. I found a lot of similar problems, but I couldn't apply for my case:

City's class:

class City < ApplicationRecord
  has_many :users
end

User's class:

class User < ApplicationRecord
  belongs_to :city
  
  validates :name, presence: true, length: { maximum: 80 }
  validates :city_id, presence: true
end

Users Controller:

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

Users View:

<%= 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

Migrate:

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 from console and browser:

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

Well, the problem is, the attributes from User's model that aren't FK they are accept by User.save method, and the FK attributes like citys_id are not. Then it gives me error message in browser saying that "Validation failed City must exist".

Thanks

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Try the following:

belongs_to :city, optional: true

According to the new docs:

> 4.1.2.11 :optional > > If you set the :optional option to true, then the presence of the > associated object won't be validated. By default, this option is set > to false.

Solution 2 - Ruby on-Rails

This comes a bit late but this is how to turn off this by default in rails 5:

config/initializers/new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false

In case you don't want to add optional: true to all your belongs_to.

I hope this helps!

Solution 3 - Ruby on-Rails

You need to add the following to the end of the belongs_to relationship statement:

optional: true

It is possible to set this on a global level so that it works in the same way as older versions of rails, but I would recommend taking the time to manually add it to the relationships that really need it as this will cause less pain in the future.

Solution 4 - Ruby on-Rails

I found out a solution to the problem "Validation failed: Class must exist" and it's better than use:

belongs_to :city, optional: true

> 4.1.2.11 :optional

> If you set the :optional option to true, then the presence of the associated object won't be validated. By default, this option is set to false.

cause you still make a validation in application level. I solve the problem making my own validation in create method and changing user_params method:

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

I didn't test this code, but it works in another project mine. I hope it can help others!

Solution 5 - Ruby on-Rails

Rails 5

If you have a belongs_to relationship to :parent then you have to pass an existing parent object or create a new one then assign to children object.

Solution 6 - Ruby on-Rails

belongs_to :city, required: false

Solution 7 - Ruby on-Rails

Rails.application.config.active_record.belongs_to_required_by_default = false

This works because the Rails 5 has true by default to disable you go under Initilizers then click on the New_frame-work and turn the true to false

Solution 8 - Ruby on-Rails

params.require(:user).permit(:name, :citys_id)

It's a mistake, isn't it? (citys_id vs city_id)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPedro Gabriel LimaView Question on Stackoverflow
Solution 1 - Ruby on-RailsIgor_MarquesView Answer on Stackoverflow
Solution 2 - Ruby on-RailsJeremieView Answer on Stackoverflow
Solution 3 - Ruby on-RailsDavid KaneView Answer on Stackoverflow
Solution 4 - Ruby on-RailsPedro Gabriel LimaView Answer on Stackoverflow
Solution 5 - Ruby on-RailsricksView Answer on Stackoverflow
Solution 6 - Ruby on-RailsPurkhalo AlexView Answer on Stackoverflow
Solution 7 - Ruby on-RailsTruth NamanyaView Answer on Stackoverflow
Solution 8 - Ruby on-Railsv.sheldeshovView Answer on Stackoverflow