2017-11-05 12 views
0

実際には一緒に作成され削除される複数のモデルがあります。 基本的に私はArticleモデルとAuthorshipモデルを持っています。著者は、ユーザーと記事の間の多対多の関係をリンクします。記事が作成されると、対応する著者も作成されます。今、これは複数回POSTすることで実現しています。Rails API:1つのリクエスト、複数のコントローラアクション

しかし、私の要求の一部しか働いていないとします。たとえば、私は悪いwifi上にあり、作成する記事の要求だけがそれを作る。それから私のデータは、作成された不正な形式の半分であり、半分の状態ではありません。

これを解決するには、すべてのデータを一度に送信してから、Railsでデータを対応するコントローラに分割します。私はこれを行ういくつかの方法を考えました。最初の方法は、コントローラが順番に各要求を処理し、それらを連鎖させることです。これは、コントローラがチェーン内の次のものを呼び出す必要があります。しかし、コントローラを別の方法で作成する場合は、コントローラのコード自体を実際に変更する必要があります。

第2の方法は、最初にデータを分割してから、各データビットでコントローラのアクションを呼び出します。この方法は私にとってはよりクリーンなようですが、ルーティングやコントローラとは独立したレイヤーで、いくらかのロジックを必要とします。私はこのロジックがどこに向かうべきかはっきりしていません(別のコントローラ、ルータ、ミドルウェア)

いずれの方法でも経験がありましたか?さらに良い方法がありますか?

おかげで、 ニコラス

答えて

1

は、私は1つの要求を持つモデルでこれを処理します。 ArticleAuthorの間にhas_manyの関係がある場合は、Articleモデルでaccept_nested_attributes_forを使用できる場合があります。次に、Authorship属性とArticle属性を1回のリクエストで渡すことができます。う

モデル/ 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 

あなたはその後、ArticleモデルにAuthor属性を渡すことができますとRails:私はあなたのコードを見ていないが、あなたはこのような何かを行うことができます

必要に応じてAuthorsを作成/更新してください。

accepts_nested_attributes_forには、blog postがあります。あなたはofficial Rails documentationでそれについて読むことができます。

ネストされた属性と、Railsが1つのコントローラアクション内で1つのWebリクエストでこれを処理する関連付けメソッドを利用することをお勧めします。

+1

あなたの 'article.rb'の最初の行はちょっとしたものです。おそらく 'class Article

+0

良い点。投稿が編集されました。 –

3

通常、このような処理(オブジェクトの作成時に関連付けられたレコードの作成)は、すべて同じトランザクション内で実行します。 Authorshipを作成するとArticleが自動的に作成される場合は、AuthorshipArticleの作成を分割することは間違いありません。 Articleの関連するAuthorshipを作成するために必要なすべてのパラメータを取り込む1つの要求が必要な場合は、両方を同じトランザクションで作成します。一つの方法は、コントローラにこのような何かを行うには、次のようになります。

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を打ったとき、両方ArticleAuthorshipの処理は同じトランザクションの一部です。だからどこかで何かが失敗した場合、すべてが失敗し、迷子/異種/不一致のデータで終わることはありません。あなたは(つまり、あなたが複数のユーザIDのparamsに取る)エンドポイント上で複数のauthorshipsを割り当てる場合

することは、最後のビットのようなものになる可能性:

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コールバックを使用します。これもトランザクションになります。しかし、上記のイディオムはもっと典型的なようです。

+0

さて、アーティクルコントローラにビルドしてください。それは理にかなっている。ありがとう! –

関連する問題