未创建关联对象,为创建的原始对象创建重复的空插入语句(Rails)

时间:2014-05-01 13:36:50

标签: ruby-on-rails ruby activerecord ruby-on-rails-4 sqlite

我有一个相当简单的有很多/属于关系模型:报告有很多记录有很多相关的出版商。属于对象的外键具有ID的父键。

但是,我无法保存任何“相关出版商”。或者更确切地说,我'可以',其中提交事务返回true,但是没有创建相关记录,并且相应的SQLite3命令没有意义。

为什么Rails生成的SQLite操作命令创建一个空记录?为什么绕过相关出版商的保存?

rails console中,某些输出被截断

> @report = Report.new => #<Report id: nil, ... >
> @record = @report.records.build(leid: 1234567890) => #<Record id: nil, leid: 1234567890, ...>
> @related_publisher = @record.related_publishers.build(sid: 9876)
 => #<RelatedPublisher id: nil, ..., sid: 9876, ...>
> @report.save
   (0.1ms)  begin transaction
  SQL (4.5ms)  INSERT INTO "reports" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", Wed, 07 May 2014 11:20:50 UTC +00:00], ["updated_at", Wed, 07 May 2014 11:20:50 UTC +00:00]]
  SQL (0.2ms)  INSERT INTO "records" ("created_at", "leid", "report_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Wed, 07 May 2014 11:20:50 UTC +00:00], ["leid", 1234567890], ["report_id", 22], ["updated_at", Wed, 07 May 2014 11:20:50 UTC +00:00]]
  SQL (0.3ms)  INSERT INTO "records" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", Wed, 07 May 2014 11:20:50 UTC +00:00], ["updated_at", Wed, 07 May 2014 11:20:50 UTC +00:00]]
   (0.7ms)  commit transaction
 => true
> RelatedPublisher.all
RelatedPublisher Load (0.3ms)  SELECT "related_publishers".* FROM "related_publishers"
 => #<ActiveRecord::Relation []>

(在Mac OSX 10.9.2上使用带有gem版本1.3.9的sqlite3 3.7.13和Mac OSX 10.9.2上的Ruby 2.0.0p353的Rails 4.0.4


应用程序/模型/ report.rb

class Report < ActiveRecord::Base
  has_many :records
end

应用程序/模型/ record.rb

class Record < ActiveRecord::Base
  belongs_to :report

  has_many :related_publishers
end

应用程序/模型/ related_publisher.rb

class RelatedPublisher < ActiveRecord::Base
  belongs_to :record
end

来自schema.rb

  create_table "records", force: true do |t|
    t.integer  "leid"
    t.integer  "sid"
    t.string   "name"
    t.string   "url"
    t.string   "join_date"
    t.string   "join_ip"
    t.string   "country"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "report_id"
    t.boolean  "ipAddressMatch"
    t.boolean  "whoisAddressMatch"
    t.integer  "recommendation"
  end

  add_index "records", ["report_id"], name: "index_records_on_report_id"

  create_table "related_publishers", force: true do |t|
    t.integer  "leid"
    t.integer  "sid"
    t.string   "name"
    t.string   "url"
    t.string   "join_date"
    t.string   "join_ip"
    t.string   "country"
    t.integer  "record_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "related_publishers", ["record_id"], name: "index_related_publishers_on_record_id"

  create_table "reports", force: true do |t|
    t.integer  "report_type"
    t.string   "upload_data_file_path"
    t.string   "completed_data_file_path"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "ltn_username"
  end

1 个答案:

答案 0 :(得分:1)

构建关联时我没有看到#new。引用Active Record Associations docs你会发现

4.3.1.14 collection.build(attributes = {}, ...)

collection.build方法返回一个或多个相关类型的新对象。这些对象将从传递的属性中实例化,并且将创建通过其外键的链接,但是尚未保存关联的对象。

这似乎是您希望在irb会话中实现的目标。在你的情况下,这应该转化为

@record.related_records.build(val: "related")
@record.save

(请注意,你save父母,它也会存储已更改的孩子)

或者你可以使用

4.3.1.15 collection.create(attributes = {})

collection.create方法返回关联类型的新对象。此对象将从传递的属性中实例化,将创建通过其外键的链接,并且一旦它通过关联模型上指定的所有验证,将保存关联的对象。

是否应立即保存新创建的记录(并且已保存父对象)。