user984621
user984621

Reputation: 48483

Rails 6 routes - how to add custom "new" route?

I'd like to add a custom rails route - the default way is something like this:

/cars/new

I'd like to keep this route available and would also want to add a route like this:

/cars/new/:manufacturer_slug

and then just in the view/controller to check what is in params and based on that show different content.

How do I do that?

I tried to add it through resources, like

resources :end do
  get 'new/:manufacturer_slug',                   to: 'cars#new'
end

or

resources :end do
  member do
    get 'new/:manufacturer_slug',                   to: 'cars#new'
  end
end

but neither version works - in both cases I just get an error about a wrong URL.

Upvotes: 0

Views: 1275

Answers (2)

max
max

Reputation: 102222

A more RESTful, conventional and altogether better solution would be to declare a nested resource.

resources :manufacturers, only: [] do
  resources :cars, 
    only: [:new, :create], 
    module: :manufacturers
end

This would declare the route /manufacturers/:manufacturer_id/cars/new. Not that just because the parameter is called manufacturer_id doesn't mean you can't use a slug instead of the primary key. Identifiers are whatever you want them to be.

This route is much less wonky as the path itself describes the relation between the two resources and its very clear that you are creating a resource that belongs to another.

module Manufactorers
  class CarsController < ApplicationController
    before_action :set_manufacturer

    # GET /manufacturers/acme/cars/new
    def new
      @car = @manufacturer.cars.new
    end

    # POST /manufacturers/acme/cars
    def create
      @car = @manufacturer.cars.new(car_params)
      if @car.save
        redirect_to @car
      else
        render :new
      end
    end

    private

    def set_manufacturer
      # adapt this to your own slugging solution
      @manufacturer = Manufacturer.find_by_slug_or_id(params[:id])
    end

    def car_params
      params.require(:car)
            .permit(:foo, :bar, :baz)
    end
    # ...
  end
end
<%= form_with model: [@manufacturer, @car] do |form| %>
  # ...
<% end %>

Upvotes: 1

hungmi
hungmi

Reputation: 405

resources :cars do
  collection do
    get 'new/:manufacturer_slug', to: 'cars#new'
  end
end

or

get 'cars/new/:manufacturer_slug', to: 'cars#new'

check the result with rails routes.

or you can just add the param at the end of url: /cars/new?manufacturer_slug=anything

Upvotes: 0

Related Questions