私は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属性は受け入れられないことです。次に、「検証に失敗した都市が存在する必要があります」というエラーメッセージがブラウザに表示されます。
ありがとう
以下を試してください:
belongs_to :city, optional: true
新しいドキュメント によると:
4.1.2.11:オプション
:optionalオプションをtrueに設定すると、関連付けられたオブジェクトの存在は検証されません。 デフォルトでは、このオプションはfalseに設定されています。
これは少し遅れますが、これはデフォルトでこれをオフにする方法 in Rails 5:
config/initializers/new_framework_defaults.rb
Rails.application.config.active_record.belongs_to_required_by_default = false
optional: true
をすべてのbelongs_to
に追加したくない場合。
これがお役に立てば幸いです!
Belongs_to関係ステートメントの最後に以下を追加する必要があります:
optional: true
これをグローバルレベルで設定して、古いバージョンのRailsと同じように機能させることができますが、実際に必要な関係に手動で追加することをお勧めします。未来。
レール5
belongs_to
と:parent
の関係がある場合は、既存の親オブジェクトを渡すか、新しい親オブジェクトを作成してから、子オブジェクトに割り当てる必要があります。
「検証に失敗しました:クラスが存在する必要がある」という問題の解決策を見つけました。使用するよりも優れています。
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
このコードはテストしませんでしたが、別のプロジェクトで動作します。他の人にも役立つことを願っています!
belongs_to :city, required: false