验证失败类必须存在

Ped*_*ima 36 validation ruby-on-rails associations belongs-to model-associations

在Rails中,我一直(小时)遇到麻烦.我发现了很多类似的问题,但我不能申请我的案子:

城市班级:

class City < ApplicationRecord
  has_many :users
end
Run Code Online (Sandbox Code Playgroud)

用户班级:

class User < ApplicationRecord
  belongs_to :city

  validates :name, presence: true, length: { maximum: 80 }
  validates :city_id, presence: true
end
Run Code Online (Sandbox Code Playgroud)

用户控制器:

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
Run Code Online (Sandbox Code Playgroud)

用户查看:

<%= 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
Run Code Online (Sandbox Code Playgroud)

迁移:

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
Run Code Online (Sandbox Code Playgroud)

控制台和浏览器的消息:

ActiveRecord::RecordInvalid (Validation failed: City must exist):
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Igo*_*ues 73

请尝试以下方法:

belongs_to :city, optional: true
Run Code Online (Sandbox Code Playgroud)

根据新的文档:

4.1.2.11:可选

如果将:optional选项设置为true,则不会验证关联对象的存在.默认情况下,此选项设置为false.

  • 哎这是一个非常恼人的问题.在`FactoryGirl`中,如果您只是为没有该片段的`User`创建工厂,在`belongs_to`类中,您将得到该错误.接得好! (3认同)

Jer*_*mie 8

这有点晚了但这是默认情况下在rails 5中关闭它的方法:

配置/初始化/ new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false
Run Code Online (Sandbox Code Playgroud)

如果你不想添加optional: true到你的所有belongs_to.

我希望这有帮助!