最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

inertiajs - Rails and Inertia.js How to Implement POST Request - Stack Overflow

programmeradmin0浏览0评论

I have a Rails 8 application which is using Inertia.js and Vue. I am not sure how to implement a redirect_to() request using Inertia.js within Rails. My attempts are not working. I am using in integrating Inertia.js into Rails.

Github repo is at

The worflow is

a) HTML button "Add to Cart" is found on /app/frontend/pages/Store/Index.vue.

# /app/frontend/pages/Store/Index.vue

<template>
  <button
    @click="addToCart(product.id)"
    class="ml-4 rounded-lg py-1 px-2 text-white bg-green-600"
    >
    Add to Cart
  </button>
</template>

<script setup lang="ts">
import axios from "axios";
import { router } from '@inertiajs/vue3';

const addToCart = async (productId: number) => {
  try {
    const response = await axios.post('/line_items',
        { product_id: productId },
        { headers: { 'X-CSRF-Token': csrfToken } } // Include CSRF token
    );

    alert('Product added to cart!');

    // Extract the cart ID from the response.
    const cartId = response.data.cart_id;

    router.visit(`/carts/${cartId}`);
  } catch (error) {
    console.error('Error adding to cart: ', error);
    alert('Failed to add product to cart.');
  }
};
</script>

b) Clicking the "Add to Cart" button goes to /app/controllers/line_items_controller.rb Create Controller action.

  • I have not been able to get Inertia.js to work work within this create action, using a Rails redirect_to().
  • So I am currently passing cart_id back to Vue as JSON.
# line_items_controller.rb

def create
    product = Product.find(params[:product_id])
    @line_item = @cart.line_items.build(product: product)

    if @line_item.save
      # redirect_to @line_item.cart, notice: "Line item was successfully created."
      # redirect_to @cart, notice: "Cart was successfully updated."
      # redirect_to inertia: cart_path(@cart), notice: "Cart was successfully updated."
      render json: { cart_id: @cart.id }
    else
      # redirect_to new_line_item_url, inertia: { errors: @line_item.errors }
      # render inertia: "Carts/Show", props: { cart: @cart, errors: @line_item.errors }
      render json: { errors: @line_item.errors.full_messages },
             status: :unprocessable_entity
    end
end # END def create

c) The LineItems Controller Create action passes cart_id back to /app/frontend/pages/Store/Index.vue where it performs router.visit('/carts/${cartId}').

Does anyone have a solution for implementing a redirect_to() Inertia.js request within Rails?

I have a Rails 8 application which is using Inertia.js and Vue. I am not sure how to implement a redirect_to() request using Inertia.js within Rails. My attempts are not working. I am using https://github/skryukov/inertia_rails-contrib in integrating Inertia.js into Rails.

Github repo is at https://github/Chrisgo-75/rails8_inertiajs_vuejs

The worflow is

a) HTML button "Add to Cart" is found on /app/frontend/pages/Store/Index.vue.

# /app/frontend/pages/Store/Index.vue

<template>
  <button
    @click="addToCart(product.id)"
    class="ml-4 rounded-lg py-1 px-2 text-white bg-green-600"
    >
    Add to Cart
  </button>
</template>

<script setup lang="ts">
import axios from "axios";
import { router } from '@inertiajs/vue3';

const addToCart = async (productId: number) => {
  try {
    const response = await axios.post('/line_items',
        { product_id: productId },
        { headers: { 'X-CSRF-Token': csrfToken } } // Include CSRF token
    );

    alert('Product added to cart!');

    // Extract the cart ID from the response.
    const cartId = response.data.cart_id;

    router.visit(`/carts/${cartId}`);
  } catch (error) {
    console.error('Error adding to cart: ', error);
    alert('Failed to add product to cart.');
  }
};
</script>

b) Clicking the "Add to Cart" button goes to /app/controllers/line_items_controller.rb Create Controller action.

  • I have not been able to get Inertia.js to work work within this create action, using a Rails redirect_to().
  • So I am currently passing cart_id back to Vue as JSON.
# line_items_controller.rb

def create
    product = Product.find(params[:product_id])
    @line_item = @cart.line_items.build(product: product)

    if @line_item.save
      # redirect_to @line_item.cart, notice: "Line item was successfully created."
      # redirect_to @cart, notice: "Cart was successfully updated."
      # redirect_to inertia: cart_path(@cart), notice: "Cart was successfully updated."
      render json: { cart_id: @cart.id }
    else
      # redirect_to new_line_item_url, inertia: { errors: @line_item.errors }
      # render inertia: "Carts/Show", props: { cart: @cart, errors: @line_item.errors }
      render json: { errors: @line_item.errors.full_messages },
             status: :unprocessable_entity
    end
end # END def create

c) The LineItems Controller Create action passes cart_id back to /app/frontend/pages/Store/Index.vue where it performs router.visit('/carts/${cartId}').

Does anyone have a solution for implementing a redirect_to() Inertia.js request within Rails?

Share Improve this question edited Mar 4 at 13:35 Chris asked Mar 3 at 13:11 ChrisChris 4236 silver badges15 bronze badges 2
  • Please include the relevant code in the question itself. Why should people both to help you if you can't be bothered to do more than just drop a link to your repo? – max Commented Mar 4 at 10:45
  • @max I have added code snippets. Thank you Max. – Chris Commented Mar 4 at 13:36
Add a comment  | 

1 Answer 1

Reset to default 0

Axios does redirect but you have to handle the final response yourself, which is what you're doing when you render instead of a redirect.

Inertia provides an api for manual requests and it handles redirects and page updates. Instead of axios.post do this:

<template>
  <button @click="addToCart(product.id)">
    Add to Cart
  </button>
</template>

<script setup>
  import { router } from '@inertiajs/vue3';

  const addToCart = (product_id) => {
    router.visit('/line_items', {
      method: 'POST',
      data: { product_id },
    });
  }
</script>

https://inertia-rails.dev/guide/manual-visits

Or use Link component:

<template>
  <Link
    href="/line_items"
    method="post"
    :data="{ product_id: product.id }"
  >
    Add to Cart
  </Link>
</template>

<script setup>
  import { Link } from '@inertiajs/vue3'
</script>

https://inertia-rails.dev/guide/links

发布评论

评论列表(0)

  1. 暂无评论