验证失败类必须存在

时间:2016-08-16 20:13:24

标签: ruby-on-rails validation associations model-associations belongs-to

我已经(小时)在Rails中遇到关联问题。我发现了很多类似的问题,但我不能申请我的案子:

城市班级:

person.firstName

用户班级:

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

嗯,问题是,用户模型中的属性不是FK,它们是User.save方法接受的,而像citys_id这样的FK属性则不是。然后它在浏览器中给出了错误消息,说“验证失败的城市必须存在”。

由于

8 个答案:

答案 0 :(得分:69)

尝试以下方法:

belongs_to :city, optional: true

根据new docs

  

4.1.2.11:可选

     

如果将:optional选项设置为true,则表示存在   相关对象将不会被验证。 默认情况下,此选项已设置   为假。

答案 1 :(得分:8)

这有点晚了但是在rails 5中默认情况下如何关闭

<强> 配置/初始化/ new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false

如果您不想将optional: true添加到所有belongs_to

我希望这有帮助!

答案 2 :(得分:4)

您需要在belongs_to关系语句的末尾添加以下内容:

optional: true

可以在全局级别设置它,以便它与旧版本的rails一样工作,但我建议花时间手动将其添加到真正需要它的关系中,因为这样会减少未来的痛苦。

答案 3 :(得分:2)

我找到了问题的解决方案&#34;验证失败:班级必须存在&#34;它比使用更好:

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

我没有测试过这段代码,但它可以在另一个项目中使用。我希望它可以帮助别人!

答案 4 :(得分:2)

Rails 5

如果您与belongs_to之间存在:parent关系,则必须传递现有父对象或创建新对象,然后分配给子对象。

答案 5 :(得分:1)

belongs_to :city, required: false

答案 6 :(得分:0)

Rails.application.config.active_record.belongs_to_required_by_default = false

这有效,因为默认情况下Rails 5具有true 要禁用您,请进入“初始化器”,然后单击“ New_frame-work”,然后将true设置为false

答案 7 :(得分:0)

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

这是一个错误,不是吗? (city s _id与city_id)