One of my Rails routes requesting favicon.ico - ruby-on-rails

I've just added resources: :favorites, nested inside resources: :deals, to my Rails app. All of a sudden, visiting the deals/deal_slug/favorites/new, after it renders, fires off a GET request to deals/favicon.ico which of course activates the show route, which fails to find anything with the slug of favicon.ico.
It appears to ONLY be the favorites/new route that causes this request, and I've tried commenting out all of favoritescontroller#new as well as the new view, with no change.
Commenting out link href="../../favicon.ico" rel="icon" in my layout fixes it of course, but I'd love to keep that in my layout and figure out why the heck this problem JUST started!
My routes file:
Rails.application.routes.draw do
# what are these??
get 'regions/index'
get 'regions/show'
root "deals#index"
resources :deals, param: :slug do
resources :favorites
end
resources :favorites
get 'my-deals', to: 'deals#my_deals', as: :my_deals_path
resources :regions, param: :slug, only: [:index, :show] do
resources :deals, only: [:index, :show], param: :slug
# resources :deals, only: [:index, :show, :edit, :destroy]
end
resource :preferences
ActiveSupport::Inflector.inflections {|inflect| inflect.irregular 'preferences', 'preferences'} # fix route helper paths so that form_for works
get '/preferences/delete_airport/:airport_id', to: 'preferences#destroy', as: 'delete_home_airport'
resources :vacations
get 'pry', to: 'application#pry'
# ------- DEVISE STUFF --------
devise_for :users, controllers: {
omniauth_callbacks: 'users/omniauth_callbacks',
preferences: 'users/preferences',
}
devise_scope :user do
get "/sign_out", to: 'devise/sessions#destroy', as: 'user_sign_out'
get "/sign_in", to: 'users/sessions#new', as: 'user_sign_in'
get "/sign_up", to: 'devise/registrations#new', as: 'user_sign_up'
get "/user/preferences", to: 'users/preferences#index', as: 'user_preferences'
get "/user/preferences/edit", to: 'users/preferences#edit', as: 'edit_user_preferences'
patch "/user/preferences/:id/edit", to: 'users/preferences#update'
end
devise_for :admins, path: 'admin', controllers: { sessions: 'admins/sessions' }
devise_scope :admin do
get "/admin", to: 'admins/sessions#portal', as: 'admin_root'
get "/admin/sign_out", to: 'devise/sessions#destroy', as: 'admin_sign_out'
end
end
FavoritesController:
class FavoritesController < ApplicationController
def new
prefs = current_user.preferences
#favorite = Favorite.new deal: Deal.find_by(slug: params[:deal_slug]), preference_id: prefs.id
end
def create
#favorite = Favorite.create(favorite_params)
redirect_to preferences_path
end
def favorite_params
params.require(:favorite).permit :preference_id, :deal_id, :comment
end
end

The request for the favicon icon is made by the browser, your code does not trigger that request.
The problem is your favicon href, you are making it relative to the current path: "../../favicon.ico" instead of absolute "/favicon.ico". You'll get the same problem if you have other routes with more than 2 levels since the route is relative.
You should add the favicon.icon somewhere on your public folder and point at it with an absolute path instead. If the icon is in /public/favicon.ico then configure the layout's favicon tag with href="/favicon.ico", if you put the icon somewhere else like /public/icons/favicon.ico then change the link tag to href="/icons/favicon.ico".

Related

Ruby on Rails: rosource RESOURCE_NAME dosent generate index route/action

im currently trying to use the resource but one problem im having , that when i do the following
resource :orders
the route /orders dosent route to OrdersController#index rather it points to the show action of the controller, how can i fix this issue ?
becuase of this problem im having to do this which i feel is kinda hack and not good
get '/orders', to: 'orders#index'
get '/orders/:id', to: 'orders#show'
this is my routes.rb file
Rails.application.routes.draw do
get '/carts', to: 'carts#index'
get '/payments', to: 'payments#index'
post '/payments', to: 'payments#add_credits'
get '/orders', to: 'orders#index'
get '/orders/:id', to: 'orders#show'
resources :users do
resource :orders, only: %i[show create index]
resource :carts, only: %i[create destroy], path: 'cart', as: 'cart'
end
resource :sessions, only: [] do
post 'login', action: :create
post 'logout', action: :destroy
get 'login', action: :new
end
resources :products
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
thanks for your answer :)
Don't use
resource :orders
use
resources :orders
You would only use resource when the item orders is a single entity in your application... which is to say you're using the plural to refer to that one item.
Move the resource for orders outside of the Users routes.
Just and FYI, you can have both the full resource outside of Users and then those restricted routes inside Users, but I'm not sure what the goal is here so it is up to you to decide that.
Rails.application.routes.draw do
get '/carts', to: 'carts#index'
get '/payments', to: 'payments#index'
post '/payments', to: 'payments#add_credits'
resources :orders
resources :users do
resource :orders, only: %i[show create index] <-- not sure if this remains here
resource :carts, only: %i[create destroy], path: 'cart', as: 'cart'
end
...

Custom Routing in Rails 5

I'm having some issues with custom routing. What I'm looking to do is remove the model from the route and dynamically use the record name.
so instead of:
site.com/events/my-event
I would like it to be:
site.com/my-event
I hacked this to work with the below code, only issue is I can't access my admin namespace as it's being treated as an event record (and any other route):
get('/:id', to: redirect do |params, request|
id = request.path.gsub("/", "")
"/events/#{id}"
end)
I know this redirect is not right, I'm just not well versed in routing options. How should this be done properly?
routes.rb
Rails.application.routes.draw do
resources :events, param: :id, path: "" do
get 'login', to: 'sessions#new', as: :login
get 'logout', to: 'sessions#destroy', as: :logout
post 'sessions', to: 'sessions#create', as: :session_create
end
namespace 'admin' do
root "events#index"
resources :sessions, only: [:create]
get 'login', to: 'sessions#new', as: :login
get 'logout', to: 'sessions#destroy', as: :logout
resources :events
end
end
Rails lets you specify what a routing URL should look like:
https://guides.rubyonrails.org/routing.html#translated-paths
You don't need redirect.
You need to match all requests to one controller/action.
get '/(*all)', to: 'home#app'
Inside this action check what is coming in params and render appropriate view.
PS: it will capture all requests, even for not found images, js, etc.
(1) To fix /admin to go to the right path, move the namespace line above the events resources so that it is matched first:
Rails routes are matched in the order they are specified 2.2 CRUD, Verbs, and Actions
# routes.rb
namespace :admin do
root "events#index"
#...
resources :events
end
resources :events, param: :name, path: ""
Use :param and :path to match for site.com/myevent instead of site.com/events/:id
Your events controller:
# events_controller.rb
class EventsController < ApplicationController
# ...
private
def set_event
#event = Event.find_by(name: params[:name])
end
end
Your admin events controller:
# admin/events_controller.rb
class Admin::EventsController < ApplicationController
# ...
private
def set_event
#event = Event.find params[:id]
end
end
TIP: To get a complete list of the available routes use rails routes in your terminal 5.1 Listing Existing Routes

Rails - Deploying to Heroku with duplicate routes

I'm deploying my Rails app that uses the clearance gem to Heroku. Everything works fine in development but I'm running into trouble with the gem generated routes I get.
When attempting to deploy to Heroku, I get the error...
ArgumentError: Invalid route name, already in use: 'sign_in'
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here:
remote: http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
I'm not seeing where to restrict the duplicates or where they would be generated with any of my resources:
Please see routes.rb file below
Routes.rb
Rails.application.routes.draw do
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, controller: "clearance/sessions", only: [:create]
resources :users, controller: "clearance/users", only: [:create] do
resource :password,
controller: "clearance/passwords",
only: [:create, :edit, :update]
end
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
get "/sign_up" => "clearance/users#new", as: "sign_up"
get 'newSignUp', to: 'signups#new'
post 'newSignUp', to: 'signups#create'
get 'newTrip', to: 'trips#new'
post 'newTrip', to: 'trips#create'
get 'trips/:id/send_itinerary' => 'trips#send_itinerary', as: :trips_send_itinerary
root 'static_pages#home'
get 'static_pages/home'
get 'static_pages/help'
get 'static_pages/about'
get 'static_pages/contact'
resources :signups
resources :tripitems
resources :trips
end
This issue has to do with the clearance gem.
I am not totally familiar with the gem, so as per usual, I checked out the github and found the following:
# config/routes.rb
if Clearance.configuration.routes_enabled?
Rails.application.routes.draw do
resources :passwords,
controller: 'clearance/passwords',
only: [:create, :new]
resource :session,
controller: 'clearance/sessions',
only: [:create]
resources :users,
controller: 'clearance/users',
only: Clearance.configuration.user_actions do
resource :password,
controller: 'clearance/passwords',
only: [:create, :edit, :update]
end
get '/sign_in' => 'clearance/sessions#new', as: 'sign_in'
delete '/sign_out' => 'clearance/sessions#destroy', as: 'sign_out'
if Clearance.configuration.allow_sign_up?
get '/sign_up' => 'clearance/users#new', as: 'sign_up'
end
end
end
This is basically creating the same routes for you, only if the config routes_enabled? is true.
You need to configure clearance as follows to handle the routes yourself:
config.routes = false
After looking at the gems GitHub, it looks like I raked the routes earlier and even though config.routes was set to false in the initializer, there was a conflict generate in the generated resources in production.
I wound up deleting the raked routes and making config.routes=true.

ui-router, devise and a user profile page

I'm trying to create a user profile page but I'm having some problems. I've used Devise for user handling in my project and I'm using AngularJS and ui-router and obviously RoR.
What I'm trying to do is to show a profile page of a user when the following URL is visited http://localhost:3000/users/1
When I visit that URL now I see my frontpage (views/layout/application.html.haml) which is obviously wrong.
In my mainCtrl.js I have
$stateProvider
.state('home', {
url: '',
templateUrl: '../assets/angular-app/templates/_search.html',
controller: 'searchCtrl'
})
.state('users.profile', {
url: '/users/{id}',
templateUrl: '../assets/angular-app/templates/_profile.html'
})
The home state works when I go to localhost:3000
But like I said, when I go to http://localhost:3000/users/1 the template _profile.html doesn't get inserted, there's not even an error if I mistype the template file name. So it looks like the state action doesn't do anything.
My expectation is that the template _profile.html gets loaded into the
%div{"ui-view" => ""}
on my application.html.haml page. But it inserts the _search template.
And this is the routes.rb if it matters,
Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
get 'sessions/create'
get 'sessions/destroy'
devise_scope :user do
root to: 'application#angular'
match '/sessions/user', to: 'devise/sessions#create', via: :post
end
resources :users do
member do
get :following, :followers
end
end
resources :relationships, only: [:create, :destroy]
get 'login/show'
get 'auth/:provider/callback', to: 'sessions#create'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
resources :sessions, only: [:create, :destroy]
resources :movies, only: [:create, :destroy, :index, :show]
end
Researching some examples I noticed the hashtag. When I added the # to my url the route states started working. Then I used html5mode enabled to remove the # and now it's working fine.

Ruby on Rails attribute routing using resources

I'm working on a preservation project where I have models for Institutions, Objects, and Files and I'm using resources in my routes file to help manage all of that. The problem I'm having is that resources uses the :id generated by Ruby on Rails for all of its routes and I would like to use a different attribute. This is particularly important for academic preservation and URL consistency. For example, I would like my show URL for an institution to read institutions/:identifier as opposed to institutions/:id, where :identifier is the attribute I have created. The problem is, I haven't been able to find any information on how to do this aside from just matching individual routes to the new ones I want which seems like a cheap hack at best and breaks a lot of my code.
This is my current routes file:
Fluctus::Application.routes.draw do
#match "institutions/", to: 'institutions#index', via: [:get]
#match "institutions/", to: 'institutions#create', via: [:post]
#match "institutions/:identifier", to: 'institutions#show', via: [:get]
#match "institutions/:identifier", to: 'institutions#update', via: [:patch]
#match "institutions/:identifier", to: 'institutions#update', via: [:put]
#match "institutions/:identifier", to: 'institutions#destroy', via: [:delete]
#match "institutions/:identifier/edit", to: 'institutions#edit', via: [:get]
#match "institutions/:identifier/events", to: 'events#index', via: [:get]
#match "institutions/new", to: 'institutions#new', via: [:get]
#
#match "objects/institution_identifier", to: 'intellectual_objects#index', via: [:get], as: "intellectual_objects_path"
#match "objects/institution_identifier", to: 'intellectual_objects#create', via: [:post]
resources :institutions do
resources :intellectual_objects, only: [:index, :create], path: 'objects'
resources :events, only: [:index]
end
resources :intellectual_objects, only: [:show, :edit, :update, :destroy], path: 'objects' do
resources :generic_files, only: :create, path: 'files'
patch "files/:id", to: 'generic_files#update', constraints: {id: /.*/}, trailing_slash: true, format: 'json'
resources :events, only: [:create, :index]
end
devise_for :users
resources :users do
patch 'update_password', on: :collection
get 'edit_password', on: :member
patch 'generate_api_key', on: :member
end
resources :generic_files, only: [:show, :destroy], path: 'files' do
resources :events, only: [:create]
end
Blacklight.add_routes(self)
mount Hydra::RoleManagement::Engine => '/'
authenticated :user do
root to: "institutions#show", as: 'authenticated_root'
# Rails 4 users must specify the 'as' option to give it a unique name
# root :to => "main#dashboard", :as => "authenticated_root"
end
root :to => "catalog#index"
end
You can see where I have attempted to match individual routes without much luck. I've also looked into FriendlyID without any luck so far. If anyone has any ideas it would be greatly appreciated. Thank you!
Unless I'm missing something here, you should just be able to stick the string you want to use into the URL where the id whould be. For example, /objects/show/1 would become /objects/show/some_string. Then in your controller you can find the object using the id parameter:
def show
#object = Object.where(:some_attribute => params[:id]).first
end

Resources