How to set default format for routing in Rails? - ruby-on-rails

There is the following code for routing:
resources :orders, only: [:create], defaults: { format: 'json' }
resources :users, only: [:create, :update], defaults: { format: 'json' }
resources :delivery_types, only: [:index], defaults: { format: 'json' }
resources :time_corrections, only: [:index], defaults: { format: 'json' }
It is possible to set default format for all resources using 1 string without 'defaults' hash on each line? Thanks.

Try something like this:
scope format: true, defaults: { format: 'json' } do
resources :orders, only: [:create]
resources :users, only: [:create, :update]
resources :delivery_types, only: [:index]
resources :time_corrections, only: [:index]
end

I'd rather add method to application_controller. And use it as before filter where I want.
class ApplicationController < ActionController::Base
...
private
...
def set_default_format
params[:format] ||= "json"
end
end
class UsersController < ApplicationController
before_filter :set_default_format, only: [:create]
...
end
In this case default format wouldn't a surprise for new developers, because usually routes.rb is big and cumbersome

That worked for me:
scope defaults: { format: 'json' } do
resources :users, only: [:index]
end

Related

Rails 6: Routing with scope for User model/controller

In my rails 6 project (development mode) i've set up a User model along with devise.
In routes.rb i have:
scope :auth do
devise_for :users
end
resources :users, except: :index
resources :articles, only: [:show, :update]
scope :passport do
resources :users, only: :index
resources :articles, except: [:show, :update]
end
Prefixes work as expected for articles but not for users.
For some reason /passport/users refering to users#index
doesn't get the users_path prefix (GET) at all.
It's without any prefix.
Request to localhost:3000/passport/users works fine.
Is there a conflict with devise?
Im missing something but what is it?
Problem not in device gem
You can try this
scope :auth do
devise_for :users
end
scope :passport do
resources :users, only: :index
resources :articles, except: [:show, :update]
end
resources :users, except: :index
resources :articles, only: [:show, :update]
I don't know why, but it works

No route matches when trying to sign up

I'm having troubles with routes in Ruby on Rails. I've configured routes this way
resources :users do
collection do
resource :registrations, only: [:show, :create]
resource :sessions, only: [:new, :create, :destroy]
resource :confirmations, only: [:show]
end
end
And I have a RegistrationsController where I have two endpoints (new, create)
class RegistrationsController < ApplicationController
skip_before_filter :authenticate!
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = t("registrations.user.success")
redirect_to :root
end
end
end
But when I do rails s and I put localhost:3000/users/registrations/create or new I get a "no route matches". And I think the route exist because If I do raake routes I get this
registrations POST /users/registrations(.:format) registrations#create
GET /users/registrations(.:format) registrations#show
I know it should be a silly mistake but I don't get it. I appreciate any help
When you define routes for registrations, you're limiting it to just [:show, :create]:
resource :registrations, only: [:show, :create]
But your controller (correctly!) is presuming that there are two routes: new (to show the registration form) and create (to create the new user). You need to change your routes so that they match your controller actions:
resources :users do
collection do
resource :registrations, only: [:new, :create] # Updated this line!
resource :sessions, only: [:new, :create, :destroy]
resource :confirmations, only: [:show]
end
end

Rails Routes for API

I am trying to create the following Routes
/plans
/plans/:plan_id/notes
/plans/:plan_id/notes/:id
/notes/:note_id/reply
/notes/:note_id/upvote
This is my Route file
resources :plans, only: [:create, :index, :show] do
resource :note, only: [:create]
resources :notes, only: [:destroy]
end
resources :notes, only: [:index] do
resource :note_replies, only: [:create, :destroy]
resources :note_upvotes, only: [:create, :destroy]
end
Is there a way to remove duplication of routes created for notes?

How can I alias or rewrite a set of resource routes to another namespace in Rails 4?

I have a bunch of resources that I want to make available at both /api/[PATH] and /api/v1/[PATH]. In other words, both /api/tasks/12 and /api/v1/tasks/12 should be routed to Api::V1::TasksController#show. However, for reasons of backward-compatibility I don't want to use external redirects - all the routing should happen internally.
This is the best I've found so far, but it requires replicating the resource declarations:
namespace :api, defaults: {format: :json} do
namespace :v1, as: 'v1' do
resource :profile, only: [:show]
resources :notifications, only: [:create]
resources :tasks, only: [:index, :create, :show, :update]
end
scope module: 'v1' do
resource :profile, only: [:show]
resources :notifications, only: [:create]
resources :tasks, only: [:index, :create, :show, :update]
end
end
Yes, I could put them in a Proc if I really wanted to avoid duplication, but that just seems ridiculous.
I tried something like match '*path', path: '/v1', via: :all (inside the first namespace) but that didn't seem to work.
Surely there's a better way of doing this?
Routes
I understand your question - you want the same routes (including controllers) to be defined for the /v1 API as the standard /api.
The best I can give is to help you define some routing concerns:
#config/routes.rb
concern :api do
resource :profile, only: [:show]
resources :notifications, only: [:create]
resources :tasks, only: [:index, :create, :show, :update]
end
namespace :api, defaults: {format: :json} do
scope module: "v1" do
concerns :api
end
namespace :v1, as: 'v1' do
concerns: :api
end
end
I know it's a bit WET, but it's the surest way to achieve what you're looking for

Refactor nested routes for common default

I have some routes for an API which all have the same defaults (format: :json):
namespace :api do
namespace :v1 do
resources :users, only: [:index, :show, :update], defaults: { format: :json }
resources :items, only: [:index, :show, :update, :destroy], defaults: { format: :json }
resources :posts, only: [:index, :show, :update], defaults: { format: :json }
resources :comments, only: [:index, :show, :update], defaults: { format: :json }
resources :flags, only: [:index, :show, :update, :create], defaults: { format: :json }
end
end
Is there a way to refactor/DRY the code to set the defaults (or even the only) in just one place for only this set of routes? The app also serves HTML at other routes, so it can't be a blanket setting for the whole app.
Move defaults: {format: :json} and the common only options at namespace level. Namespace have them as an option.
namespace :api, defaults: { format: :json }, only: [:index, :show, :update] do
namespace :v1 do
resources :users
resources :items, only: [:index, :show, :update, :destroy]
resources :posts
resources :comments
resources :flags, only: [:index, :show, :update, :create]
end
end
You can use iterator like the following:
[:users, :items, :posts, :comments, :flags].each do |res|
resources res, only:[...], defaults: {}
end
but I see you have different only so you can also pass it to iterator

Resources