No route matches [GET] "/account/undefined" - ruby-on-rails

In my rails app, I have a namespace in my route file,
namespace :account do
resources :activities
end
My controller is
class Account::ActivitiesController < Account::AccountController
before_action :find_activity, only: [:show, :edit]
def index
#activities = Activity.all
end
def show
end
private
def find_activity
#activity = Activity.find(params[:id])
end
def activity_params
params.require(:activity).permit(:name, :description)
end
end
In my index view I'n trying to access the show page by do this:
= #activities.each do |activity|
= link_to "show", account_activity_path(activity)
When I'm running rake route, I get this result:
account_activities GET /account/activities(.:format) account/activities#index
POST /account/activities(.:format) account/activities#create
new_account_activity GET /account/activities/new(.:format) account/activities#new
edit_account_activity GET /account/activities/:id/edit(.:format) account/activities#edit
account_activity GET /account/activities/:id(.:format) account/activities#show
PATCH /account/activities/:id(.:format) account/activities#update
PUT /account/activities/:id(.:format) account/activities#update
DELETE /account/activities/:id(.:format) account/activities#destroy
When I'm taping directly localhost:3000:/account/activities/1, I'm going to the right page, but when I click on the show link in my index view, I'm getting this error:
No route matches [GET] "/account/undefined"
I'm using rails 4, and everything worked fine until today. I don't see what's happen so if you have any ideas, could be great
Thanks a lot

For anyone else that stumbles upon this issue, hopefully this will help. Check your javascript events!
I had a shared JS file between two HTML pages. Two different people were working on each page and both people attached a CHANGE event handler to an element ID.
$("#site").change(function() {
var url = $(this).data('url');
window.location = url;
}
Both events were executing on each page, causing the UNDEFINED route.

Related

How do I get my link_to to go to my show method?

I’m using Rails 5. I’m having trouble linking to a show method in my controller. I have this defined in my config/routes
resources :scenarios do
resources :confidential_memos
end
and in a view, I put this
<td><%= link_to "#{subscription.scenario.title}", scenarios_path(subscription.scenario) %>
in my controller I have the show method
class ScenariosController < ApplicationController
def show
#scenario = Scenario.find(params[:id])
end
but when I click on the link, I get the error
The action 'index' could not be found for ScenariosController
How do I get my link to get to my show action?
scenarios_path uses the plural "scenarios" so it is looking for several scenarios and that maps to the index action, hence your error. To show a single scenario you'd use the singular:
scenario_path(subscription.scenario)
If you only have a show action then you might want to be explicit in your routes:
resources :scenarios, :only => %i[ show ] do
#...
end
so that you catch the error sooner.
You could solve this yourself by doing a rake routes and looking for the show action that you're interested in.

Redirecting to another view in rails

I'm trying to build a link shortener. The intended behavior is that on the first page (new) the user inserts his long link and presses a button, then he gets redirected to an another page called result, where a preset message will be waiting for him, along with both his short and long link.
I'm struggling with controllers, however, as no matter what I do something always comes wrong. Right now my controller looks like this:
class UrlsController < ApplicationController
def new
#short_url = Url.new
end
def create
#short_url = Url.new(url_params)
if #short_url.save
flash[:short_id] = #short_url.id
redirect_to "/urls/result"
else
render action: "new"
end
end
def show
Url.find(params[:id])
##short_url_yield =
redirect_to #short_url.url
end
def result
end
private
def url_params
params.require(:url).permit(:url)
end
end
And the routes.rb:
Rails.application.routes.draw do
resources :urls, :only => [:show, :new, :create, :result]
get 'urls/result' => 'urls#result'
root to: redirect('/urls/new')
end
When I submit the link, however, rails returns the following error:
Couldn't find Url with 'id'=result
Extracted source (around line #17):
def show
Url.find(params[:id])
##short_url_yield =
redirect_to #short_url.url
end
It seems I don't understand the logic behind it. What's going wrong? Isn't the show bit supposed to be a redirect that happens when I click the shortified link?
Rails routes have priority in the order they are defined. Since your SHOW route declaration is before get 'urls/result' => 'urls#result' the url gets matched as /urls/id=result.
Simply move your custom route above the resources block or use a collection block.
resources :urls, :only => [:show, :new, :create, :result] do
collection do
get 'result'
end
end
Using the collection and member blocks tells Rails to give priority to the routes inside over the normal CRUD actions such as show.

Rails UrlGeneration Error on form_for after upgrade to 4.2

I just upgraded rails from 4.0 to 4.2 and it seems to have caused an error in one of my form_fors. Now when I visit the new view, I get:
Error:
ActionController::UrlGenerationError at /billing/providers/new
No route matches {:action=>"show", :controller=>"billing/provider_agencies", :id=>nil} missing required keys: [:id]
View (error from this line):
= form_for #provider_agency, url: billing_provider_agency_path(#provider_agency) do |f|
...
Routes:
namespace :billing do
resources :provider_agencies, path: "providers" do
resources :invoices
end
end
Controller:
class Billing::ProviderAgenciesController < BillingController
before_action :set_provider_agency, only: [:show, :edit, :update, :destroy]
def index
...
end
def show
#users = #provider_agency.users
end
def destroy
...
end
def new
#provider_agency = Agency::Provider.new
end
def create
...
end
def edit
...
end
def update
...
end
protected
def provider_agency_params
params.require(:agency_provider).permit(:id, :name,...
...
])
end
def set_provider_agency
#provider_agency = #agency.agencies.find(params[:id])
end
end
I had to define the url in the form_for because of the way I namespace the resources in my routes. Defining that url in the form_for used to work in any view including new. Now the new view seems to be calling the show action, and looking for the #provider_agency that hasn't been created/saved yet. To be clear, this breaks the new view but all other view's still work.
I went back to check the commits and none of these files have changed, the error simply begins when I upgrade to Rail 4.2.
Any ideas are greatly appreciated, thanks!
EDIT:
Here is the relevant portion of my rake routes too:
billing_provider_agencies GET /billing/providers(.:format) billing/provider_agencies#index
POST /billing/providers(.:format) billing/provider_agencies#create
new_billing_provider_agency GET /billing/providers/new(.:format) billing/provider_agencies#new
edit_billing_provider_agency GET /billing/providers/:id/edit(.:format) billing/provider_agencies#edit
billing_provider_agency GET /billing/providers/:id(.:format) billing/provider_agencies#show
PATCH /billing/providers/:id(.:format) billing/provider_agencies#update
PUT /billing/providers/:id(.:format) billing/provider_agencies#update
DELETE /billing/providers/:id(.:format) billing/provider_agencies#destroy
I had a similar issue.
I modified the form_for syntax little bit.
For nested model,old syntax:
form_for(#child, url: parent_child_path(#parent,#child))
to newer syntax
form_for([#parent,#child])
For independent model
form_for(#model, url: model_path(#model))
to
form_for(#model)
Refer here

Why does the params "id" key change from params[:id] into params[:model_id]?

When I go to the characters controller, show action, all the normal params[:id] is as how it should be according to REST.
In the show view, I render a partial. In that partial, I have a link that goes to the vote_socionics action. This action is defined under a socionics_votes module, which gets included by the characters controller. (I have it set up this way because I have other controllers that also include this module).
My problem is that when I click on this link, and it goes to the set_votable private method within the socionics_votes_module.rb file, the params[:id] is no longer present. Using pry, I found that it actually turns into params[:character_id]
Questions:
1) Why does this happen (is it because it goes to a "different" controller, even if it's a module?)
2) How do I work around this? I would think that it would be more elegant to have it be params[:id], instead of having to do an if-else to account for both keys.
characters_controller.rb
class CharactersController < ApplicationController
include SocionicsVotesModule
def show
#character = Character.find(params[:id])
end
characters/show.html.haml
= render partial: 'votes/vote_socionics',
locals: { votable: #votable, votable_name: #votable_name, socionics: #socionics }
_vote_socionics.html.haml
= link_to content_tag(:div,"a"), send("#{votable_name}_vote_socionics_path", votable, vote_type: "#{s.type_two_im_raw}"),
id: "vote-#{s.type_two_im_raw}",
class: "#{current_user.voted_on?(votable) ? 'voted' : 'not-voted'}",
method: :post,
data: { id: "#{s.type_two_im_raw}" }
socionics_votes_module.rb
module SocionicsVotesController
extend ActiveSupport::Concern
included do
before_action :set_votable
end
private
def set_votable
votable_constant = controller_name.singularize.camelize.constantize
#votable = votable_constant.find(params[:id]) # This is where it fails, since there is no params[:id], and rather, params[:character_id]
end
def set_votable_name
#votable_name = controller_name.singularize.downcase
end
routes.rb
concern :socionics_votes do
post 'vote_socionics'
end
resources :characters, concerns: :socionics_votes
resources :celebrities, concerns: :socionics_votes
resources :users, concerns: :socionics_votes
The URL of the link in the partial when hovered over.
localhost..../characters/4-cc/vote_socionics?vote_type=neti
Something like .find(params[:id] || params[:"#{#votable_name}_id"]) didn't work, and seems silly.
You need to add the vote_socionics route as a member of the resource:
concern :socionics_votes do
member do
post 'vote_socionics'
end
end
This way the id parameter gets set correctly

Rails - nesting routes within the same controller

I'm totally confused trying to route my app. I have a bunch of events, and each should have a photo gallery.
However I would like to keep everything within the same EVENT controller (btw, another question - how reasonable is that?). So the user can go on the Edit Event page and have a menu on the left side with links, one of which will be his gallery.
So I've added this to my event controller:
def gallery
#event = Event.find(params[:id])
end
The URI should be (I guess?): site/event/777/gallery/edit
How can I route that? And what will be the _path?
Thank you for any help
I can think of no good reason to do this. Creating another file is trivial, have a GalleriesController with the usual show/edit/update/etc methods.
In your routes:
resources :events do
resources :galleries
galleries_controller.rb:
class GalleriesController < ApplicationController
# GET /events/1/galleries/1/edit
def edit
#event = Event.find(params[:event_id])
#gallery = #event.galleries.find(params[:id])
end
end
The following configuration in your config/routes.rb should give you what you want:
resources :events do
resources :galleries
end
And this will give you event_galleries_path. And, this will give you event_galleries_path. Following are the seven paths the above configuration will provide:
event_galleries GET /events/:event_id/galleries(.:format) galleries#index
POST /events/:event_id/galleries(.:format) galleries#create
new_event_gallery GET /events/:event_id/galleries/new(.:format) galleries#new
edit_event_gallery GET /events/:event_id/galleries/:id/edit(.:format) galleries#edit
event_gallery GET /events/:event_id/galleries/:id(.:format) galleries#show
PUT /events/:event_id/galleries/:id(.:format) galleries#update
DELETE /events/:event_id/galleries/:id(.:format) galleries#destroy
The edit named route is: edit_event_gallery_path.
Then instead of adding the gallery method in your EventsController, so you'd create your edit, show and other other actions in your GalleriesController.
# /events/:event_id/galleries/:id/edit
def edit
#gallery = Gallery.find(params[:id])
end
# /events/:event_id/galleries/:id
def show
#event = Event.find(params[:event_id])
# And your galleries, something like this
#galleries = #event.galleries.find(params[:id])
end

Resources