【问题标题】:Validation failed Class must exist验证失败类必须存在
【发布时间】:2016-12-23 08:18:24
【问题描述】:

我在 Rails 中遇到了(几个小时)的关联问题。发现很多类似的问题,但是申请不了我的case:

城市等级:

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 模型的非 FK 属性被 User.save 方法接受,而像 citys_id 这样的 FK 属性则不是。然后它在浏览器中给我错误消息说“验证失败的城市必须存在”。

谢谢

【问题讨论】:

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


【解决方案1】:

尝试以下方法:

belongs_to :city, optional: true

根据new docs

4.1.2.11:可选

如果您将 :optional 选项设置为 true,则存在 关联对象不会被验证。 默认设置此选项 为假。

【讨论】:

  • 嘿伊戈尔.. 很高兴在这里看到一个 BR :) 谢谢你的回答。有效!我之前找到了这个答案,但直到现在我才尝试过。原因是在我看来,这个 option 使属性器在服务器级别的验证无效。所以我检查确定,当我给外键 city_id 一个错误的值时,错误消息只是在数据库尝试进行插入查询后出现,在我看来,这似乎是一个数据库级别的验证。无论如何,我将在服务器级别进行自己的验证来解决这个问题。我想给你一个UPVOTE,但我没有足够的分数:(哈哈
  • 哦,我不知道!哈哈哈不错:)
  • 啊,这是一个很烦人的问题。在FactoryGirl 中,如果您只是为User 创建一个工厂而没有那个sn-p,那么在belongs_to 类中,您将收到该错误。好收获!
【解决方案2】:

这有点晚了,但这是 如何在 Rails 5 中默认关闭它

config/initializers/new_framework_defaults.rb

Rails.application.config.active_record.belongs_to_required_by_default = false

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

我希望这会有所帮助!

【讨论】:

  • 我昨天升级到 Mac OS Mojave,现在我收到了这些验证错误,即使我的项目已将其设置为 false(因为我们升级到 Rails 5 早在什么时候)。有人知道是什么原因造成的吗?
【解决方案3】:

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

optional: true

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

【讨论】:

    【解决方案4】:

    我找到了“验证失败:类必须存在”问题的解决方案,比使用要好:

    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
    

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

    【讨论】:

      【解决方案5】:

      Rails 5

      如果您与:parentbelongs_to 关系,那么您必须传递一个现有的父对象或创建一个新对象然后分配给子对象。

      【讨论】:

      • 你能举个例子吗?因为我不想使用 optional: true
      • 我还需要一个例子。学习rails,我就是找不到我该怎么做。
      【解决方案6】:
      belongs_to :city, required: false
      

      【讨论】:

      • 请尝试给出解释以回答问题,而不仅仅是邮政编码。谢谢。
      【解决方案7】:
      Rails.application.config.active_record.belongs_to_required_by_default = false
      

      这是因为 Rails 5 默认设置为 true 禁用你去 Initilizers 然后点击 New_frame-work 并将 true 变为 false

      【讨论】:

        【解决方案8】:
        params.require(:user).permit(:name, :citys_id)
        

        这是一个错误,不是吗? (城市s_id vs city_id)

        【讨论】:

        • 是的。许可证上的值必须与来自视图的值匹配。提交后,您可以在控制台上看到这些值。
        • 您的错误帮助我了解我有类似的问题:我在字段名称上交换了两个字符。
        猜你喜欢
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        • 2020-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多