2016-09-14 48 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'是不能接受的。 –