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
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.
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.
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
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
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