web-dev-qa-db-ja.com

検証に失敗しましたクラスが存在する必要があります

私はRailsのアソシエーションで(数時間)問題を抱えています。似たような問題をたくさん見つけましたが、私のケースに応募できませんでした。

市のクラス:

class City < ApplicationRecord
  has_many :users
end

ユーザーのクラス:

class User < ApplicationRecord
  belongs_to :city

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

ユーザーコントローラー:

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

ユーザービュー:

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

移行:

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

コンソールとブラウザーからのメッセージ:

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

問題は、User.saveメソッドで受け入れられるFKではないユーザーモデルの属性と、citys_idなどのFK属性は受け入れられないことです。次に、「検証に失敗した都市が存在する必要があります」というエラーメッセージがブラウザに表示されます。

ありがとう

34

以下を試してください:

belongs_to :city, optional: true

新しいドキュメント によると:

4.1.2.11:オプション

:optionalオプションをtrueに設定すると、関連付けられたオブジェクトの存在は検証されません。 デフォルトでは、このオプションはfalseに設定されています。

72
Igor_Marques

これは少し遅れますが、これはデフォルトでこれをオフにする方法 in Rails 5:

config/initializers/new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false

optional: trueをすべてのbelongs_toに追加したくない場合。

これがお役に立てば幸いです!

8
Jeremie

Belongs_to関係ステートメントの最後に以下を追加する必要があります:

optional: true

これをグローバルレベルで設定して、古いバージョンのRailsと同じように機能させることができますが、実際に必要な関係に手動で追加することをお勧めします。未来。

4
David Kane

レール5

belongs_to:parentの関係がある場合は、既存の親オブジェクトを渡すか、新しい親オブジェクトを作成してから、子オブジェクトに割り当てる必要があります。

2
ricks

「検証に失敗しました:クラスが存在する必要がある」という問題の解決策を見つけました。使用するよりも優れています。

belongs_to :city, optional: true

4.1.2.11:オプション

:optionalオプションをtrueに設定すると、関連付けられたオブジェクトの存在は検証されません。デフォルトでは、このオプションはfalseに設定されています。

あなたはまだアプリケーションレベルで検証を行います。 createメソッドで独自の検証を行い、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

このコードはテストしませんでしたが、別のプロジェクトで動作します。他の人にも役立つことを願っています!

2
belongs_to :city, required: false
1
Purkhalo Alex