我正在使用Rails和Angular,并试图通过前端的JSON PUT请求获得一个简单的关联来更新。
协会:Article has_many :categories, through: :article_categories
文章模型:
class Article < ActiveRecord::Base
validates :title, presence: true, uniqueness: true
validates :body, presence: true
has_many :article_categories
has_many :categories, through: :article_categories
accepts_nested_attributes_for :categories
end
我在更新title
和body
时没有遇到任何问题,但我无法更新文章的类别。
以下是相关的控制器部件
def update
@article = Article.find(params[:id])
if @article.update(article_params)
render json: @article, status: 200
end
end
private
def article_params
params.require(:article).permit(:title, :body,
categories_attributes: [:name, :id])
end
我的传入JSON看起来像这样,间隔开以使其更具可读性:
Started PUT "/api/v1/articles/6" for 127.0.0.1 at 2014-06-01 17:53:04 +0900
Processing by Api::V1::ArticlesController#update as HTML
Parameters: {"title"=>"new title", "body"=>"blablabla", "id"=>"6", "categories"=>
[{"name"=>"Ruby", "id"=>1}, {"name"=>"Javascript", "id"=>2}, {"name"=>"HTML", "id"=>3},
{"name"=>"CSS", "id"=>4}],
"categories_attributes"=>[{"name"=>"Ruby", "id"=>1},
{"name"=>"Javascript", "id"=>2}, {"name"=>"HTML", "id"=>3}, {"name"=>"CSS", "id"=>4}],
"article"=>{"id"=>"6", "title"=>"new title", "body"=>"blablabla"}}
我得到的唯一反馈是article id
不是列入白名单的参数。不是R categories_attributes
什么是Rails在采用嵌套属性时所寻找的?为什么不抱怨categories
参数没有被列入白名单?
答案 0 :(得分:1)
我们had this problem before - 您基本上绕过join model
,这会阻止您的应用程序正常运行。
嵌套关联
基本上,您需要在传递article_categories
数据之前将关联数据传递到categories
模型:
#app/models/article.rb
Class Article < ActiveRecord::Base
...
accepts_nested_attributes_for :article_categories
end
#app/models/article_category.rb
Class ArticleCategory < ActiveRecord::Base
belongs_to :category
belongs_to :article
accepts_nested_attributes_for :category
end
#app/controllers/articles_controller.rb
def new
@article = Article.new
@article.article_categories.build.build_category
end
def create
@article = Article.new(article_params)
@article.save
end
private
def article_params
params.require(:article).permit(:article, :attributes, article_categories_attributes: [categories_attributes: [:category, :options]] )
end
#app/view/articles/new.html.erb
<%= form_for @article do |f| %>
<%= f.fiels_for :article_categories do |ac| %>
<%= ac.fields_For :categories do |c| %>
<%= c.text_field :your_field &>
<% end %>
<% end %>
<% end %>
答案 1 :(得分:0)
这里有几个问题:
我的json格式不正确。这些类别没有嵌套在article
中,这就是为什么rails没有抛出验证错误的原因。我改变了角度前端来发布这个:
{"article"=>{"title"=>"sdfsd", "body"=>"sdf", "category_ids"=>[1, 2, 3]}}
我的angular $ scope包含类别ID和名称,因此我必须编写一个函数来解析ID并将它们转储到数组中。烦。
接下来,由于ArticleCategory
上的验证,使用此JSON格式创建文章失败。我将inverse_of
添加到我的模型https://github.com/rails/rails/issues/5178,然后在创建包含类别的新文章并绕过连接模型时验证将会通过。如果我理解正确,这是Richard Peck回答的另一种解决方案。
最终模型看起来像这样:
class Article < ActiveRecord::Base
validates :title, presence: true, uniqueness: true
validates :body, presence: true
has_many :article_categories, inverse_of: :article
has_many :categories, through: :article_categories
end
class Category < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
has_many :article_categories, inverse_of: :category
has_many :articles, through: :article_categories
end
class ArticleCategory < ActiveRecord::Base
belongs_to :article, inverse_of: :article_categories
belongs_to :category, inverse_of: :article_categories
validates :category, :article, presence: true
end