I want to show a simple HTML template, so I added a new empty action to my controller:
def calulator
end
And created the view calculator.html.erb . Then added a link to it:
<%= link_to 'Calculator', {:controller => "mycontroller", :action => "calculator"} %>
When I click it my log shows the following error:
ActionController::UnknownAction (No action responded to show. Actions: calculator, create, destroy, edit, index, new, and update):
Why is looking for a "show" action ? I have map.resources for the controller, as I done it with scaffolding
Any ideas?
You need to add a custom route pointing to the action 'calculator'.
Something like this:
map.connect 'mycontroller/calculator', :controller => 'mycontroller', :action => 'calculator'
You can define members and collections for resources.
map.resources :samples, :member => {:calculator => :get}
Member means that it relates to an instance of the resources. For example /samples/1/calculator. If it doesn't relate to an instance you can define it for the collection and can be access via /samples/calculator.
map.resources :samples, :collection => {:calculator => :get}
This also creates a helper method calculator_samples_path for the collection and calculator_sample_path(sample) for a member. For more on this have a look at Railscast Episode 35.
You are getting No action responded to show because you have the controller routed as map.resources. When you do that, rails sets up several routes for you. One of which is show, which maps every get request matching /mycontroller/somevalue to the show action with somevalue as the id (params[:id]). In mycontroller, there is no show action, as seen in the error message.
To fix this, Nils or Trevoke's answer should work just fine.
map.resources documentation
Related
Has anybody experienced routes mysteriously becoming undetectable when using current_page? in Rails 3? Even with a fully generated scaffold complete with routes, a view, and a controller, I am getting a "No route matches" error.
Here's the code:
if current_page?(:controller => 'users', :action => "show")
If I add a "match" command to routes.rb, it works fine, but why would I need to do that if the resources have already been created? What am I missing?
If you just want to test the current controller, you can do the following:
if params[:controller] == 'users'
Similarly, if you're using a namespaced controller, you can just use a slash to separate the namespace(s) from the controller name, e.g.:
if params[:controller] == 'advertising/users'
You're missing the id parameter from this helper:
current_page?(:controller => "users", :action => "show", :id => "1")
It expects you to pass a full route through. If you don't want this and only want to match on the controller and action then I would recommend coding your own.
Depending on your routes, to look for a generic show action without ID you could look for e.g. !current_page?(:controller => "users", :action => "index").
i prefer writing the routes of my Rails applications by hand and i now have a situation where i am not sure what is the best way to do things. I want to have a building controller that shows a different page for every building like :
building/town_center
building/sawmill
..
Each of the above should have its own action and view page. I would normally create a route like:
scope :path => '/building', :controller => :building do
get '/view/:slug' => :view, :as => 'view_building'
end
But this only specifies a single action that would then need to call another internal controller method to redirect to the needed template to show. So, i would like your opinion, would you just specify a different route for every building(and action) explicitly ? Or just redirect in the view_building action ?
I think you are after something like this:
match "/building/:name", :to => "buildings#show", :as => :building
Then in your controller action 'show' just render template for the building name:
render :template => 'buildings/#{params[:name]}'
I created a new file in app/views/students called courses.html.erb
Then I try to reference it at app/views/students/show.html.erb:
<%= link_to 'courses', courses_student_path(#student) %>
However I am getting
undefined method `courses_student_path' for #<#:0x1052d1648>
What step did I miss?
Note that you never link to views. It is always some action in some controller which in turn renders that view. In this case your action is courses in students controller and you need to create a route for it.
Assuming you already had :students resource defined in config/routes.rb:
resources :students do
get 'courses', :on => :member
end
This will give you urls like students/1/courses and route helpers courses_student_path and courses_student_url.
http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
Let's say I have a Ruby on Rails blogging application with a Post model. By default you would be able to read posts by http://.../post/id. I've added a route
map.connect ':title', :controller => 'posts', :action => 'show'
that will accept http://.../title (titles are unique) and the controller will do a query for the title and display the page. However when I am now calling <%= link_to h(post.title), post %> in a view, Rails still gives me links of the type post/id.
Is it possible to get Rails to automatically create the pretty links for me in this case?
If you are willing to accept: http:/.../1234-title-text you can just do:
def to_param
[id, title.parameterize].join("-")
end
AR::Base.find ignores the bit after the id, so it "just works".
To make the /title go away, try naming your route:
map.post ':id', :controller => 'posts', :action => 'show', :conditions => {:id => /[0-9]+-.*/ }
Ensure this route appears after any map.resources :posts call.
You can override ActiveRecord's to_param method and make it return the title. By doing so, you don't need to make its own route for it. Just remember to URL encode it.
What might be a better solution is to take a look at what The Ruby Toolbox has to offer when it comes to permalinks. I think using one of these will be better than to fixing it yourself via to_param.
I would use a permalink database column, a route, and I normally skip using link_to in favor of faster html anchor tags.
Setting your route like:
map.connect '/post/:permalink', :controller => 'post', :action => 'show'
then in posts_controller's show:
link = params[:permalink]
#post = Post.find_by_permalink(link)
You link would then be
Link
then in your create method, before save, for generating the permalink
#post = Post.new(params[:post])
#post.permalink = #post.subject.parameterize
if #post.save
#ect
There is a Gem for you to get this done perfectly
https://github.com/rsl/stringex
I'm struggling here with a problem:
I have a controller questions which has action new.
Whenever I need to create new question, I'm typing
/questions/new
What changes to routes.rb should I make to change the URI to
/questions/ask
Thank you.
Valve.
Try this:
map.ask_question '/questions/ask', :controller => 'questions', :action => 'new'
Then you'll have a named route and you can:
link_to "Ask a question", ask_question_path
If you are using RESTful routes maybe you'd like to use map.resources for your questions.
To rename the action urls you may do this:
map.resources :questions, :path_names => { :new => 'ask', :delete => 'withdraw' }
(I added delete for the sake of the example)
Which version of rails?
Generally the default route should catch anything like /:controller/:action, so you could just create an ask method in your questions controller. Take a look at the api documentation for named_route and map_resource if you want something a bit smoother to work with.