【问题标题】:Rails POSTing JSON for accepts_nested_attributesRails 为 Accepts_nested_attributes_for 发布 JSON
【发布时间】:2014-06-01 09:07:39
【问题描述】:

我正在使用 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

更新titlebody 没有问题,但我无法更新文章的类别。

这里是相关的控制器部分

        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 不是白名单参数。 categories_attributes 不是 Rails 在使用嵌套属性时所寻找的吗?为什么它不抱怨 categories 参数没有被列入白名单?

【问题讨论】:

标签: ruby-on-rails json


【解决方案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 %>

【讨论】:

  • 我尝试了一下,这让我发现问题出在我的 JSON 格式上 - 类别的参数没有嵌套在文章下,干杯
  • 没问题!很高兴它有帮助!使用API 的情况如何?这是我尚未开始的事情
  • 到目前为止非常简单 - 困难的事情将是身份验证和嵌套资源。 codeschool 有一个很好的关于构建 rails api 的课程
【解决方案2】:

这里有几个问题:

我的 json 格式不正确。这些类别没有嵌套在 article 中,这就是为什么 rails 没有抛出验证错误。我改变了角度前端来发布这个:

{"article"=>{"title"=>"sdfsd", "body"=>"sdf", "category_ids"=>[1, 2, 3]}}

我的角度 $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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多