我有多个模型在实践中一起创建和删除。 基本上我有一个文章模型和一个作者模型。作者关系链接用户和文章之间的多对多关系。创建文章时,还会创建相应的作者身份。现在,这是通过POSTing多次实现的。
但是,请说只有我的部分要求有效。例如,我的wifi很糟糕,只有创建文章请求才能通过。然后我的数据处于格式错误的一半创建,一半不是状态。
要解决这个问题,我想一次发送所有数据,然后让Rails将数据拆分成相应的控制器。我想过几种方法可以做到这一点。第一种方法是让控制器依次处理每个请求,将它们链接在一起。这将要求控制器调用链中的下一个控制器。然而,这看起来很严格,因为如果我决定以不同的方式组合控制器,我将不得不实际修改控制器代码本身。
第二种方法首先分割数据,然后用每一位数据调用控制器动作。这种方式对我来说似乎更干净,但它需要路由中的某些逻辑或独立于控制器的层。我真的不清楚这个逻辑应该去哪里(另一个控制器?路由器?中间件?)
有没有人有这两种方法的经验?还有更好的方法吗?
谢谢, 尼古拉斯
答案 0 :(得分:3)
通常你想做这样的事情 - 在对象创建上创建相关记录 - 所有这些都在同一个事务中。如果在Authorship
创建时自动创建Article
,我绝对不会考虑放弃创建Authorship
和Article
。您希望单个请求接收所有必需参数以创建Article
和其关联的Authorship
,然后在同一事务中创建两者。一种方法是在控制器中做这样的事情:
class Authorship
belongs_to :user
belongs_to :article
end
class Article
has_many :authorships
has_many :users, through: :authorships
end
class ArticlesController
def create
@article = Article.new({title: params[:title], stuff: [:stuff]...})
@article.authorships.build(article: @article, user_id: params[:user_id])
if @article.save
then do stuff...
end
end
end
这样,当您点击@article.save
时,Article
和Authorship
的处理都是同一交易的一部分。因此,如果某些事情在任何地方都失败了,那么整个事情就会失败,并且你最终不会得到流浪/不同/不一致的数据。
如果你想在端点上分配多个作者身份(即你接受多个用户id参数),那么最后一点可能会变成:
class ArticlesController
def create
@article = Article.new({title: params[:title], stuff: [:stuff]...})
params[:user_ids].each do |id|
@article.authorships.build(article: @article, user_id: id)
end
if @article.save
then do stuff...
end
end
end
您还可以通过虚拟属性和before_save
或before_create
回调将此类关联对象创建卸载到模型中,这也是事务性的。但上述成语似乎更为典型。
答案 1 :(得分:2)
我会在一个请求的模型中处理这个问题。如果您在has_many
和Article
之间存在Author
关系,则可以在accept_nested_attributes_for
模型上使用Article
。然后,您可以在一个请求中传递Authorship
个属性以及Article
属性。
我没有看到你的代码,但你可以这样做:
<强>模型/ article.rb 强>
class Article < ActiveRecord::Base
has_many :authors, through: :authorship # you may also need a class_name: param
accepts_nested_attributes_for: :authors
end
然后,您可以将Author
个属性传递给Article
模型,Rails会根据需要创建/更新Authors
。
这是Accept_nested_attributes_for上的一个好blog post。您可以在official Rails documentation。
中阅读相关内容我建议利用嵌套属性和关联方法Rails让您在一个控制器操作中通过一个Web请求处理此问题。