I am looking to modify various attributes linked to Rails

My Desire for Reality

I am looking to update multiple related values in Rails by sending an update request from JavaScript. While creating data was seamless, I encountered difficulties when attempting to update it.

#Code

JavaScript*

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

    // Mapping out 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')
      })
  },

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

// Issue with updating values
  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
      }
    })
  }

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

}

Rails controller


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

model/post

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

model/post_item

class PostItem < ApplicationRecord
belongs_to :post

end

Error

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)

What I attempted on my own

① I tried using post_all, but it didn't work because post_all is used directly in the model.

Answer №1

The main purpose of using nested attributes is to facilitate updating child elements through the parent element:

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 
      
      # use different parameter whitelists for updating and creating 
      # without needing comments to explain them 
      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 

It's important to avoid using render json: "OK", as it is considered an anti-pattern. Provide meaningful JSON responses that the client can utilize or simply return headers. Utilize appropriate HTTP status codes to communicate the success or failure of operations to the client.

If you need to update a specific post item separately, consider implementing a distinct PATCH /api/v1/post_items/:id route.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to optimize reactive values using the Vue composition API?

Imagine I have a block of code like this... const computedStyle = computed(() => normalizeStyle([undefined, styleProp, undefined]) ); const computedClass = computed(() => normalizeClass([ "button", classProp, { "b ...

Get the Vue.js package from Node.js by downloading the zip file

I am having trouble downloading a zip file from nodejs using vuejs. The issue I am facing is that an odd underscore appears around the fileName when the dialog box pops up. If I manually set the fileName like this: const fileName = "xmlFile.zip"; Then t ...

What is the best way to detect if a user has reached the end of a container div while implementing Infinite Scroll

I am in the process of implementing infinite scroll on our website's dashboard, but I am currently facing a challenge in determining the bottom of the container div in my jsfiddle mockup. The original function works on a blank page with no container ...

Mastering Meteor: Techniques for Manipulating Mongodb Data in Real Time Display

Within my Meteor application, I have accomplished the successful publication of data from the server and its subscription on the client side. Instead of directly displaying raw data on the client's screen, I am interested in performing some calculatio ...

The chart refreshes whenever there is a change in the component's state

Whenever I click the button to use the changeState method, the state changes and the MoreInfo component appears. However, the chart is being drawn again as shown in this GIF: Below is the code snippet: import React from 'react' import './Ho ...

Update your mappings for the city of Istanbul when utilizing both TypeScript and Babel

Currently, I am facing the challenge of generating code coverage for my TypeScript project using remap Istanbul. The issue arises due to the usage of async/await in my code, which TypeScript cannot transpile into ES5 directly. To circumvent this limitation ...

What is the best way to access an excel file using JavaScript and Protractor?

Is it possible to read an Excel file dynamically in JavaScript and iterate through cell values using row and column counts, without converting it into a JSON object? I have searched through several posts on Stack Overflow but have not found a solution yet. ...

Scan across a lineup of pictures

I am looking to showcase a series of images in a horizontal alignment, but I want to avoid overloading the screen width. My goal is to allow users to navigate through the images using their mouse - when they move right within the image container, I want t ...

How can I use lodash to iterate through and remove whitespace from array elements?

I am currently working on a project involving demo lodash functionality, and I have encountered some unexpected behavior. Within an array of cars, there are various non-string elements mixed in. My goal is to iterate through each element of the array, rem ...

Innovative JavaScript function

Seeking a solution for my JavaScript function that should only be executed when the browser screen width exceeds 1024px. if ($(window).width() > 1024) { An issue arises when a user initially loads the webpage on an 800px browser screen and then resize ...

Managing PHP multiple follow-up options in HTML select fields

My goal is to design a form that includes multiple follow-up select fields. These fields will be populated from an array with 3 elements: ID, Name, and followingID. The followingID corresponds to an ID in the array, helping us determine the hierarchical la ...

Using the HTMLTextAreaElement object in Vue.js

I'm utilizing the Laravel package "laracasts/utilities" to transmit Laravel variables to JavaScript files. Below is the code snippet from my controller: JavaScript::put([ 'description' => $room->description ]); He ...

Is it permissible to assign the same element as a child to multiple parent elements in jQuery?

Imagine you have the following HTML structure: <div id="first"></div> <div id="second"></div> Now, if you use JavaScript and JQuery to perform the following actions: var $child = $("<span id='child'>Hello</span ...

Looking to include some extra padding when an item is displayed - jQuery

So, I'm working on a jQuery code snippet that controls the visibility of a rectangle element: $("#rectangle").hide(); $("#toggle-rec").click(function () { $("#rectangle").toggle(2000); }); This code hides the rectangle initially and toggles it ...

Why does my React.js application still display outdated data from my Express server even after refreshing the webpage?

I have been working on a website using React.js and Express.js, following an online example to set up the basic code. I encountered an issue where the frontend did not update when I made a minor change to the array sent by Express.js. Express - users.js f ...

When navigating between Dynamic Pages using NuxtLink, the store data is not accessible

Check out the demo below. Click here for stackblitz When transitioning from a top page to a post page, the correct content is displayed. However, moving from one post page to another does not display the correct content immediately. Reloading the page w ...

Enhance your Vuetify data table by incorporating an extra column header complete with an icon or

I am in the process of developing a custom table using Vuetify and I have encountered the need to include an additional column that contains an icon button. This button will serve as a toggle for displaying headers, represented by a 3 dots toggle menu opti ...

Adding Logging Features in ASP.NET

I am currently working with an .ascx file that contains both JavaScript and div elements. I need to add a log statement inside a function for troubleshooting purposes. Can someone please guide me on how to achieve this? Below is a snippet of my code: fu ...

How can JQuery be used to implement "scrolling" buttons and automatically update the main page with fresh data?

I am attempting to achieve the following: 1 - Use jQuery to update index.html with the content from output.html (only update when there are differences in data, and ideally only update the parts that have changed). 2 - Add two buttons in the header ...

How to implement the ECharts animated bar chart in Angular version 16?

The animated bar chart in ECharts functions perfectly on Stackblitz. You can check it out here in the Stackblitz Angular 16 demo. However, attempting to run the same demo in a local Angular 16 project led to the following errors. Error: src/app/animated- ...