我有三个简单关联的模型。
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" }
}
}
如果博客存在,请将条目添加到博客中。我正在实施&#39;条目#create&#39;方法和我想要做的是像
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的第一个节点必须是&#34;条目&#34;不是&#34;博客&#34;)
我到目前为止尝试的是添加&#34; accepts_nested_attributes_for&#34;在Entry模型中。
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试图创建&#34;博客&#34;使用此代码的条目但由于&#34; blog_attributes&#34;而失败不包含&#39; user_id&#39;。我可以将user_id添加到我的控制器中的参数中,但由于我正在编写@user.entries.create
,它应该告诉我现在正在处理哪个用户,这看起来很尴尬。
有没有什么好方法可以让它全部按照我想要的方式工作? (或者我做错了什么?)
答案 0 :(得分:0)
好的,从您的参赛模式中删除accepts_nested_attributes_for :blog
在您的博客模型中添加了accepts_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