【问题标题】:I want to update multiple values ​associated with Rails我想更新与 Rails 关联的多个值
【发布时间】:2021-09-06 13:19:09
【问题描述】:

我想要实现的目标

我想更新 Rails 中相关的多个值。 从 JavaScript 发送更新请求并更新 Rails 中的数据。 创建的时候没有问题,但是更新不了。

#代码

JavaScript*

export const actions = {
  // Post the book selected by the user
  post (context) {
    const list = context.state.todos.list
    const selectedBook = context.state.book.selectedBook

    // Send to array
    const postItemsAttributes =
      list.map((item) => {
        return {
          content: item.content,
          status: item.status
        }
      })

    // plugin/bookInfo  $title,$author,$image
    this.$axios.$post(url.POST_API + 'posts', {
      post: {
        title: this.$title(selectedBook),
        author: this.$author(selectedBook),
        image: this.$image(selectedBook),
        post_items_attributes: postItemsAttributes
      }
    })
      .then((responseBook) => {
        context.commit('book/userBook', responseBook)
        context.commit('book/clearBook')
        context.commit('todos/clear')
      })
  },

//////////////////////////////////////////////////////////////////////////////////

// Value cannot be updated
  update (context) {
    const list = context.state.todos.list
    const bookId = context.state.book.selectedBook.id
    const content =
    list.map((item) => {
      return {
        content: item.content,
        status: false
      }
    })
    this.$axios.$patch(url.POST_API + 'posts/' + bookId, {
      post: {
        post_items_attributes: content
      }
    })
  }

//////////////////////////////////////////////////////////////////////////////////

}

导轨 控制器


class Api::V1::PostsController < ApplicationController

    def create
        posts = Post.new(post_params)
        if posts.save
            render json: "OK", status: 200
        else
            render json: "EEEOR", status: 500
        end
    end

     def update
        post = Post.find(params[:id])
        post.post_items.update(content_params)
     end
     


        private
              # update
            def content_params
                params.require(:post).permit(post_items_attributes:[:id, :content, :status])
            end
            #create
         def post_params
                params.require(:post).permit(:title, :author, :image, post_items_attributes: [:id, :content, :status])
         end
end

模特/帖子

class Post < ApplicationRecord
    has_many :post_items, dependent: :destroy
    accepts_nested_attributes_for :post_items, allow_destroy: true

    validates :title, presence: true
    validates :author, presence: true
    validates :image, presence: true
end

模型/post_item

class PostItem < ApplicationRecord
belongs_to :post

end

错误

api_1    | Started PATCH "/api/v1/posts/16" for 172.29.0.1 at 2021-09-06 22:15:10 +0900
api_1    | Processing by Api::V1::PostsController#update as HTML
api_1    |   Parameters: {"post"=>{"post_items_attributes"=>[{"content"=>"Test", "status"=>false}]}, "id"=>"16"}
api_1    |   Post Load (13.0ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2  [["id", 16], ["LIMIT", 1]]
api_1    |   ↳ app/controllers/api/v1/posts_controller.rb:23:in `update'
api_1    |   PostItem Load (15.4ms)  SELECT "post_items".* FROM "post_items" WHERE "post_items"."post_id" = $1  [["post_id", 16]]
api_1    |   ↳ app/controllers/api/v1/posts_controller.rb:24:in `update'
api_1    | Completed 204 No Content in 49ms (ActiveRecord: 29.5ms | Allocations: 1576)

我自己尝试过的

①我尝试使用post_all,但是没有成功,因为post_all是直接在模型中使用的。

【问题讨论】:

  • 尝试找出是 Nuxt 还是 Rails 问题。为此,请直接在后端应用程序本身上尝试 Rails 方法。然后,如果它有效,请尝试使用 Nuxt 调试您发送的内容。
  • 在控制器#update方法中,它应该是post.update(content_params) b/c模型Post有一个方法post_items_attributes=由(假定的)accepts_nested_attributes_for :post_items创建(你确实有不是吗?)。然后你需要渲染并返回一些东西给浏览器(你没有返回任何东西,这就是你在日志中看到No Content的原因。
  • 除了@LesNightingill 的出色建议之外,您实际上需要检查创建和更新记录是否成功并返回正确的响应。如果您假设客户端将始终发送有效输入,请准备好感到非常失望。
  • @Les Nightingill 是的,我用的是accepts_nested_attributes_for。果然现在状态是200。

标签: javascript ruby-on-rails vue.js nuxt.js


【解决方案1】:

嵌套属性的全部意义在于您通过父级更新子级:

module Api 
  module V1
    class PostsController < ApplicationController

      # POST /api/v1/posts
      def create
        post = Post.new(create_params)
        if post.save
          render json: post, status: :created,
          location: [:api, :v1, post]
        else
          render json: { errors: post.errors.full_messages },
          status: :unprocessable_entity # not 500 - Internal Server Error!
        end
      end

      # PATCH /api/v1/posts/1
      def update
        if post.update(update_params)
          head :ok 
          # you can also return the updated record
          # this is useful if you have any server side transformations 
          # to the record 
          # render json: post, status: :ok
        else
          render json: { errors: post.errors.full_messages },
          status: :unprocessable_entity 
        end
      end
      
      private
      # just a memoizing convenience method to keep it DRY
      def post 
        @post ||= Post.find(params[:id])
      end 
      
      # if you need to separate the whitelists for updating and creating 
      # use names which don't require comments 
      def update_params
        params.require(:post)
        .permit(
          post_items_attributes: post_item_params
        )
      end

      def create_params
        params.require(:post)
        .permit(
          :title, :author, :image, 
          post_items_attributes: post_item_params
        )
      end
      
      def post_item_params
        [:id, :content, :status]
      end
    end
  end 
end 

请注意,render json: "OK" 是一种反模式。返回客户端可以实际使用的有意义的 JSON,或者根本不返回任何(只是标头)。使用语义正确的 HTTP 状态码告诉客户端操作是否成功。

如果您想单独更新帖子项目,您将创建一个单独的PATCH /api/v1/post_items/:id 路由。

【讨论】:

  • 感谢您指出干燥和 Json 的响应。当我按照您的建议使用 post_items_attributes: post_item_params 的参数时出现错误。 ActiveModel::UnknownAttributeError (unknown attribute 'post_items_attributes' for PostItem.):
  • 这很奇怪 - 你在 Post 中有 accepts_nested_attributes_for :post_items_attributes 吗?
  • 我已经在Rails模型中设置了accepts_nested_attributes_for,它可以正常创建,但是只有更新不起作用。编辑问题文本以添加所有代码。
  • 这个错误没有任何意义。您实际上是否使用了答案中的代码?它清楚地将输入传递给 Post 的实例,而不是像您的问题中那样 PostItem 。我能想到的唯一解释是你运行了错误的代码。
  • 我们已经复制并使用了这些值。错误消失了,现在可以保存。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 2011-07-14
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 2011-01-30
  • 2016-05-30
相关资源
最近更新 更多