我想预览模型在保存时的外观,而不会保存到数据库中。
我正在使用@event.attributes =
,因为它会分配但不会将@event
的属性保存到数据库中。
但是,当我还尝试分配audiences
关联时,Rails会将新记录插入audiences_events
连接表。不酷。有没有办法在不插入连接表的情况下预览这些新关联的样子?
class Event < ActiveRecord::Base
has_and_belongs_to_many :audiences # And vice versa for the Audience model.
end
class EventsController < ApplicationController
def preview
@event = Event.find(params[:id])
@event.attributes = event_params
end
private
def event_params
params[:event].permit(:name, :start_time, :audiences => [:id, :name]
end
end
我想到的可能的解决方案,但不知道该怎么做:
任何有关这些的帮助都会很棒!
更新
在阅读下面的大答案之后,我最终编写了这个服务类,它将非嵌套属性分配给Event模型,然后在每个嵌套的params上调用collection.build。我做了一点点。很高兴收到意见/建议。
答案 0 :(得分:5)
在这些docs中你有:
何时保存对象?
将对象分配给has_and_belongs_to_many关联时,将自动保存该对象(以便更新连接表)。如果在一个语句中分配多个对象,则它们都将被保存。
如果要在不保存对象的情况下将对象分配给has_and_belongs_to_many关联,请使用
collection.build
方法。
对于Rails 3来说,这是一个很好的答案,可以解决一些相同的问题
答案 1 :(得分:4)
创建transactions非常简单:
Event.transaction do
@event.audiences.create!
@event.audiences.first.destroy!
end
或者
@event.transaction do
@event.audiences.create!
@event.audiences.first.destroy!
end
请注意,使用“bang”方法create!
和destroy!
,与返回false create
的{{1}}不同,如果失败并导致事务处理,则会引发异常回滚。
您还可以通过提升create!
来手动触发事务中任何位置的回滚。
ActiveRecord::Rollback
实例化一个新的相关对象而不保存。
build
答案 2 :(得分:1)
我知道这是一个非常老的问题,但是我找到了一个最适合我的解决方案,希望它可以节省其他人的时间:
class A
has_many :bs, class_name 'B'
end
class B
belongs_to :a, class_name: 'A'
end
a.bs.target.clear
new_bs.each {|new_b| a.bs.build new_b.attributes.except('created_at', 'updated_at', 'id') }
在执行a.bs = new_bs