我有2个型号,假设 model1 和 model2 。 model1 有很多 model2 。 model2 属于 model1 。同时保存 model1 和 model2 。
class Model1 < ActiveRecord::Base
has_many :model2s
end
class Model2 < ActiveRecord::Base
belongs_to :model1
end
def create
@mod1 = Model1.new(model1_params)
id = Model1.last.id + 1
@mod2 = Model2.new(model1_id: id)
if @mod1.save && @mod2.save
redirect root_path
else
render 'edit'
end
end
该解决方案没问题,直到我删除了model1的最后一条记录。如何在创建之前获取model1的最后一条记录。
答案 0 :(得分:2)
执行此操作的最多铁路方式如下:
def create
@mod1 = Model1.new(model1_params)
@mod1.model2.build({args if you have them}) # this will only work if you have the relationship set up
if @mod1.save
# @mod1 is now saved along with model 2 who now has its ID
# @mod1.id returns id, Model2.last returns model2 ID, Model2.last.model1_id returns Model1 ID
#you can now delete model 1 if you wanted to, just make sure you don't have dependent destroy on in the model1.
redirect root_path
else
render 'edit'
end
end
希望它有所帮助!
答案 1 :(得分:1)
如果你的Model1和Model2是子类ActiveRecord::Base
,那么就不需要手动设置id,实际上它是一个反模式。
Rails使用ActiveRecord::Base
来为模式支持的类建模。假设您有一个名为model1s
的数据库表。当你像这样创建一个Model1类时
class Model1 < ActiveRecord::Base
end
Rails知道相应的数据库表是models1
(从名称中推断出来),并在保存新的Model1记录后自动生成一个id。 id通常是一个自动递增的整数。这当然取决于底层数据库引擎(MySQL,Postgresql,SQLite,...)
所以,在你的例子中,你可以做到
success = false
@mod1 = Model1.new(model1_params)
if @mod1.save
@mod2 = Model2.new(model1_id: model1.id)
success = true if @mod2.save
end
success ? redirect_to(root_path) : render('edit')
更多提示。 Model2的model1_id
属性看起来像是一个外键。您应该考虑利用has_many / has_one / belongs_to关联以更多Rails惯用方式完成您想要的工作
class Model1 < ActiveRecord::Base
has_one :model2
end
class Model2 < ActiveRecord::Base
belongs_to :model1
end
# Then you can do (one of the many options)
@mod1 = Model1.create(params)
@mod1.model2.create
检查ActiveRecord上的Rails指南非常有用。
我认为您正在使用ActiveRecord,因为您正在使用.last
和.save
方法。我希望我的直觉是正确的。
答案 2 :(得分:0)
无法获取尚未创建的记录的ID。 解决方案的最佳答案是首先保存@ mod1。并获取其id的ID。
def create
@mod1 = Model1.new(model1_params)
if @mod1.save && Model2.create(model1_id: @mod1.id)
# @mod1 is now saved to the database. So @mod1.id will return id.
redirect root_path
else
render 'edit'
end
end