2016-09-14 6 views
0

シンプルアソシエーションを持つ3つのモデルがあります。ネストされたモデルのエントリをhas_manyとthroughを使って作成する

class User < ActiveRecord::Base 
    has_many :blogs 
end 

class Blog < ActiveRecord::Base 
    # Blog has 'title' column 
    belongs_to :user 
    has_many :entries 
end 

class Entry < ActiveRecord::Base 
    # Entry has 'article' column 
    belongs_to :blog 
end 

新しいエントリを作成するためのJSON APIを作成しています。 1つの特別な要件は、Blogが存在しない場合に作成することです。 JSON入力は次のようになります

{ "entry" : 
      { "article" : "my first blog entry", 
      "blog" : 
        { "title": "My new blog" } 
      } 
} 

ブログが存在する場合は、ブログにエントリを追加してください。私は、「エントリ#作成」メソッドを実装していると私は手動で最初にJSONを解析し、ブログのオブジェクトを作成し、エントリを作成する必要があれば私は何をしたい私はここにお願いしたいのは

def create 
    @user = Users.find(params[:user_id]) # :user_id is given in URL 
    # I want to do something like 
    # @user.entries.create(params[:entry]) 
    #  or 
    # @user.create(params[:entry]) 
    # but this doesn't work. 
end 

のようなものがあるさオブジェクト。可能であれば、モデルにそのような入力を受け入れて正しく動作させたいと思っています。

別の可能な解決策は、APIを変更して、ブログコントローラにそれを作ると

{ "blog" : 
      { "title" : "My new blog", 
      "article_attributes" : 
        { "article": "my first blog entry" } 
      } 
    } 

のようなJSONを受け入れることですが、理由はいくつかの理由で、私はこのようなAPIを作ることはできません。 (JSONの最初のノードは「ブログ」ではなく「エントリー」でなければなりません)

これまでエントリーモデルに「accepts_nested_attributes_for」を追加しました。その後、

class Entry < ActiveRecord::Base 
    # Entry has 'article' column 
    belongs_to :blog 
    accepts_nested_attributes_for :blog 
end 

など

{ "entry" : 
      { "article" : "my first blog entry", 
      "blog_attributes" : 
        { "title": "My new blog" } 
      } 
} 

をJSONを投稿するには、コントローラ

@user.entries.create(params[:entry]) 

に「blog_attributesので、Railsは、このコードで "ブログ" エントリを作成しようとしますが、失敗したようです"には 'user_id'は含まれません。私は私のコントローラのparamsにuser_idを追加することができますが、私が今作業しているユーザを教えてくれる@user.entries.createを書いているので、見苦しくなります。

私が望むようにすべての機能を有効にする良い方法はありますか? (?または私は完全に間違って何かをやっている)

+0

'accepts_nested_attributes_for'機能は、他の方法で動作します。関係がそのように機能するので、ブログがエントリのネストされた属性を受け入れるようにすることができます。エントリーがその親(ブログ)の属性を受け入れるのはちょっと後ろのようですね。 – Frost

+0

はい、私がやっていることは、通常のオブジェクト作成とは反対です。しかし、それは今私がしたいことです。 'accepts_nested_attributes_for'はちょうど私の裁判です。私は、これにいくつかの良い練習やパターンがあるかどうかを知りたい。 –

+1

私はあなたがそれにエントリを追加する前にブログを作成する必要があると思うので、残念ながら、ここでは 'accepts_nested_attributes_for'はあなたの友人だとは思わない。 – Frost

答えて

0

[OK]をあなたのエントリーモデル

からそして、あなたのブログのモデルでaccepts_nested_attributes_for :blogを削除し、あなたのJSONでaccepts_nested_attributes_for :entries, reject_if: :all_blank, allow_destroy: true

を入れて次の操作を行います。

{ "blog" : 
      { "title" : "My new blog", 
      "entry" : 
        { "article": "my first blog entry" } 
      } 
} 

blogs_controller.rbでこれを行う:

とあなたのblogs_controller。RB新しいアクション:

def new 
@blog = Blog.new 
@blog.entries.build 
end 

はあなたのblogs_controllerでアクションを作成します//:

def create 
    @user = Users.find(params[:user_id]) # :user_id is given in URL 
    @user.blog.create(blog_params) 
end 
+0

私がこの質問に述べたように、最初のノードが「blog」であるJSONを使用することは認められません。 –

関連する問題