【问题标题】:Rails Create method Validation Error with one to one associationRails 创建具有一对一关联的方法验证错误
【发布时间】:2016-07-28 16:32:07
【问题描述】:

我一直在 Coursera 上学习 ruby​​ on rails,并且专门学习一对一关联模块。我试图在我自己的系统上模拟教程中的一对一关联示例,但是我得到了 ActiveRecord::RecordInvalid 错误。这就是我为达到这一点所做的工作:

1) rails g 模型 person first_name last_name 2) 耙分贝:迁移 3) rails g model personal_info height:float weight:float person references 4) 耙分贝:迁移 5)迁移20160725143537_create_people.rb代码如下:

class CreatePeople < ActiveRecord::Migration[5.0]
 def change
   create_table :people do |t|
    t.string :first_name
    t.integer :age
    t.string :last_name
    t.timestamps
  end
 end
end

6) Migration 20160727184247_create_personal_infos.rb 代码如下:-

class CreatePersonalInfos < ActiveRecord::Migration[5.0]
  def change
    create_table :personal_infos do |t|
      t.float :height
      t.float :weight
      t.references :person, foreign_key: true

      t.timestamps null: false
   end
end

结束

7) person.rb 中的代码如下:

class Person < ApplicationRecord
  has_one :personal_info
end

8)personal_info.rb中的代码如下:-

class PersonalInfo < ApplicationRecord
  belongs_to :person
end

9)seeds.rb中的代码如下:-

Person.destroy_all

Person.create! [
{first_name: "Kalman", last_name: "Smith", age: 33, login: "kman", pass: "abc123"},
{first_name: "John", last_name: "Whatever", age: 27, login: "john1", pass: "123abc"},
{first_name: "Michael", last_name: "Smith", age: 15, login: "mike", pass: "not_telling"},
{first_name: "Josh", last_name: "Oreck", age: 57, login: "josh", pass: "password1"},
{first_name: "John", last_name: "Smith", age: 27, login: "john2", pass: "no_idea"},
{first_name: "Bill", last_name: "Gates", age: 75, login: "bill", pass: "windows3.1"},
{first_name: "LeBron", last_name: "James", age: 30, login: "bron", pass: "need more rings"},]

10) 现在我进入 rails 控制台 (rails c) 并输入以下内容: pi1 = PersonalInfo.create!(高度:6.2,重量:220.0)。这是当我收到上述错误时:

irb(main):002:0> pi1 = PersonalInfo.create!(height:6.2, weight:220.0)

(0.0ms)  begin transaction
(0.0ms)  rollback transaction
    ActiveRecord::RecordInvalid: Validation failed: Person must exist
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/validations.rb:78:in `raise_validation_error'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/validations.rb:50:in `save!'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/attribute_methods/dirty.rb:30:in `save!'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/transactions.rb:324:in `block in save!'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/transactions.rb:395:in `block in with_transaction_returning_status'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `block in transaction'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:189:in `within_new_transaction'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `transaction'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/transactions.rb:211:in `transaction'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/transactions.rb:392:in `with_transaction_returning_status'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/transactions.rb:324:in `save!'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/suppressor.rb:45:in `save!'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/activerecord-5.0.0/lib/active_record/persistence.rb:51:in `create!'
    from (irb):2
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-5.0.0/lib/rails/commands/console.rb:65:in `start'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-5.0.0/lib/rails/commands/console_helper.rb:9:in `start'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:78:in `console'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-5.0.0/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
    from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-5.0.0/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'irb(main):003:0>

我正在使用 Rails 5。 我非常感谢你们帮助我解决这个错误。提前致谢

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    根据您的要求,您已在 Person 和 PersonalInfo 之间定义了 has_one 关联。 最好先创建PersonalInfo,你应该先创建Person,然后再创建PersonalInfo,比如:

    @person = Person.create!(first_name: "Kalman", last_name: "Smith", age: 33, login: "kman", pass: "abc123")
    

    现在您可以创建个人信息

    @person.personal_info.create(height:6.2, weight:220.0)
    

    我想它会对你有所帮助。不过,如果您有任何疑问,请告诉我。

    【讨论】:

    • 非常感谢您的回复。因此,在 coursera 视频教程中,他们展示的示例中,他们最初为记录设置 nil 外键值,然后直接在与之关联的表上设置该记录。例如,person1 = Person.find_by!(first_name:"BIll") pi1 = PersonalInfo.create(height:6.2, weight:220.0) person1.personal_info = pi1
    • 这是我试图做的只是为了模拟教程中显示的示例,但事实证明,在 Rails 5 中,为了获得 nil 外键值,我们需要在旁边添加 optional:true相应类中的 belongs_to 语句。这就是我最终做的事情,尽管你是对的,因为坚持外键约束并首先创建父类记录然后在子类记录中创建它的引用更有意义。再次感谢您!
    【解决方案2】:

    您需要设置person_id:

    PersonalInfo.create!(person_id: 1, height:6.2, weight:220.0)
    

    【讨论】:

    • 感谢您的帮助!
    【解决方案3】:

    正如您在 CreatePersonalInfos 迁移中所见,person 引用具有外键约束。这意味着如果没有关联的Person,您将无法创建PersonalInfo。您可以通过提供有效的person_id来创建它

    PersonalInfo.create!(height:6.2, weight:220.0, person_id:1)
    

    或通过 Person 上的关联

    @person.create_personal_info(height:6.2, weight:220.0)
    

    您还可以在迁移中删除foreign_key 选项以删除数据库级约束。

    【讨论】:

    • 感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2021-11-30
    • 2023-01-21
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多