2016-09-14 57 views
0

爲嵌套模型創建條目我有三個簡單關聯的模型。使用has_many和

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來創建新的Entry。一個特殊的要求是創建Blog,如果不存在的話。 JSON輸入應該類似於

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

如果博客存在,則將條目添加到博客中。我執行「項#創建」方法和我想要做的是一樣的東西

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 

我想在這裏問是,如果我必須手動解析JSON第一和創建博客對象,然後創建條目目的。如果可能,我想讓模型接受這樣的輸入並正確工作。

另一種可能的解決辦法是改變了API,使其在博客控制器和接受JSON像

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

但由於某些原因,我不能讓這樣的API。 (JSON的第一個節點必須是「入口」而不是「博客」)

我到目前爲止嘗試的是在Entry模型中添加「accep_nested_attributes_for」。

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

,然後交JSON像

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

然後在控制器

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

看來Rails的嘗試創建 「博客」 這個代碼條目,但失敗了,因爲「blog_attributes 「不包含'user_id'。我可以將user_id添加到控制器中的參數中,但由於我正在編寫@user.entries.create,它看起來很尷尬,它應該告訴我正在處理哪個用戶。

有沒有什麼好的方法可以讓它一切按我想要的方式工作? (?還是我做一些完全錯誤的)

+0

的'accepts_nested_attributes_for'功能工作的其他方式。您可以讓Blog接受條目的嵌套屬性,因爲這種關係是以這種方式工作的。讓Entry接受它的父類(Blog)的屬性似乎有點落後,不是嗎? – Frost

+0

是的,我正在做的是與通常的對象創建相反。但那是我現在想要做的。 'accept_nested_attributes_for'只是我的試用版,我不確定它是否有效。我想知道是否有一些好的做法或模式。 –

+1

我認爲你需要在添加條目之前創建博客,所以我不認爲'accept_nested_attributes_for'是你的朋友,不幸的是。 – Frost

回答

0

確定從入門車型

而在你的博客模式刪除accepts_nested_attributes_for :blogaccepts_nested_attributes_for :entries, reject_if: :all_blank, allow_destroy: true

在你的JSON做到這一點:

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

在您的blogs_controller.rb中執行以下操作:

def blog_params 
    params.require(:blog).permit(:id, :title, entries_attributes: [:id, :article, :_destroy]) 
end 

和您的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

正如我在問題中所述,使用JSON的第一個節點是'blog'是不能接受的。 –