Unexpected dot from helper method - ruby-on-rails-3

I have the following routings
PosTracker::Application.routes.draw do
get "home/index"
resources :pos
resources :apis
match 'update_data' => 'home#update', :as => :update, :via => :get
root :to => "home#index"
end
Now, when using the link_to helper method:
link_to "text", pos_path(starbase)
I get the following route /pos.13 instead of /pos/13. Obviously, this won't produce valid output. How can I fix this?
Edit: Relevant controller:
class PosController < ApplicationController
# GET /pos
# GET /pos.xml
def index
#do stuff
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #pos }
end
end
# GET /pos/1
# GET /pos/1.xml
def show
#pos = Pos.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #pos }
end
end
end

It seems to me like Rails is recognizing pos_path as your #index action url helper. Generally it will take the symbol you pass to resources and singularize it for a #show action.
The url helper you want to use would be
link_to "text", po_path(starbase)
You can generally find the name of the helper methods by running
rake routes
Or to get the helper for a specific controller
rake routes CONTROLLER=pos

Related

Very strange routing error in rails 3

I got a controller called MeController. It has a bunch of actions like spaces and projects.
The spaces action does the following:
def spaces
#spaces = current_user.spaces
respond_to do |format|
format.html # show.html.erb
format.json { render json: #note }
end
end
The view just renders an other index template like:
<%= render :template => "spaces/index" %>
This works perfectly but now the stränge part begins... :S
This is the project action:
def projects
#projects = current_user.projects
respond_to do |format|
format.html # index.html.erb
format.json { render json: #projects }
end
end
The view renders also an index template:
<%= render :template => "projects/index" %>
But for the projects I get the following error:
Routing Error
No route matches {:action=>"edit", :controller=>"spaces", :id=>nil}
I just don't get why it should be an Routine Error with the action edit and the controller spaces. :/
Here are my routes:
# Profiles & Current User
resources :profiles
get "me" => "profiles#show", :as => "current_user"
get "me/spaces", :as => "current_user_spaces"
get "me/projects", :as => "current_user_projects"
get "me/tasks", :as => "current_user_tasks"
get "me/notes", :as => "current_user_notes"
get "me/discussions", :as => "current_user_discussions"
get "me/files", :as => "current_user_files"
# Permissions
resources :permissions
resources :spaces do
resources :projects do
resources :tasks
resources :notes
end
end
devise_for :users
root :to => redirect("/me/spaces")
Hope somebody has a hint for me! :)
So my guess would be:
In your template (projects/index), you are using url helpers like url_for or link_to with links to specific projects. The issue is that the projects have nested routing within your spaces resource. That's why you have to provide any url helper with a reference to both, space and project when you want it to generate an url to a project.
RoutingError is also thrown in case an url helper doesn't know how to construct an url.
This is a long shot, but I hope it helps.

No route matches {:action=>"show", :controller=>"restaurants"}

If I want to go with my home page clicking on the map localhost:3000/maps gets out this error No route matches {:action=>"show", :controller=>"restaurants"}
controllers/maps_controller.rb
def index
#maps = Map.all
#json = Map.all.to_gmaps4rails do |map, marker|
marker.infowindow info_for_restaurant(map.restaurant)
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
def show
#map = Map.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #map }
end
end
private
def info_for_restaurant(restaurant)
link_to restaurant_path do
content_tag("h2") do
restaurant.name
end
end
end
routes.rb
resources :restaurants
resources :maps
This is answer for my question:
controllers/maps_controller.rb
def index
#maps = Map.all
#json = Map.all.to_gmaps4rails do |map, marker|
marker.infowindow render_to_string(:partial => "/maps/maps_link",
:layout => false, :locals => { :map => map})
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
views/maps/_maps_link.html.erb
<div class="map-link">
<h2><%= link_to map.restaurant.title, map.restaurant %></h2>
</div>
You referred to restaurant_path within info_for_restaurant, which is part of MapsController. Rails met error here.
You need to either define the restaurant_path in restaurant controller, or comment out this function in maps controller at this moment.
Your approach is wrong in several levels. Let's work on them, one at a time:
1) Your call to the route helper is wrong:
restaurant_path is the route helper for a show action. A show action needs an id parameter to be valid. Your call is missing a parameter.
So, your code must be something like this:
def info_for_restaurant(restaurant)
link_to restaurant_path(restaurant) do
content_tag("h2") do
restaurant.name
end
end
end
To see the parameters needed for each action, you can run rake routes on the console.
However, this does not solve the problem, as you're also:
2) Calling view helpers from your controller
link_to and content_tag are view helper methods, and you don't want to bother your controller with view issues. So, the best way to solve this problem is to move your info_for_restaurant method to a helper, and call it from a view instead.
So, now, your controller will not assign anything to #json, and the last line of your view will look like this:
<%= gmaps4rails #maps.to_gmaps4rails {|map, marker| marker.infowindow info_for_restaurant(map.restaurant) } %>

Rails 3.2.2 - Possible to add custom node to as_json

As it's not currently possible for me to use a json templating engine (jbuilder or rabl) as per Rails3 ActionView Template Handlers doesn't work on Production Server I'm wondering how to best change this controller action to include a custom node with as_json (or something else)
class Mobile::AndroidUsersController < SecureMobileUserController
skip_before_filter :authorize, :only => :create
respond_to :json
# POST /mobile_users
# POST /mobile_users.xml
def create
#mobile_user = AndroidUser.find_by_auth(params[:mobile_user][:auth])
unless #mobile_user
#mobile_user = AndroidUser.new(params[:mobile_user])
else
#mobile_user.attributes = params[:mobile_user]
end
respond_to do |format|
if #mobile_user.save
format.json #Add a custom token node here
else
:unprocessable_entity }
format.json { render json: #mobile_user.errors, status: :unprocessable_entity }
:unprocessable_entity }
end
end
end
end
I just need to add a custom node called token that has a value that I get from calling a method on the MobileUser class
:token => MobileUser.next_token
You can change the call to as_json like this:
format.json {render :json => #mobile_user.as_json(:methods => [:next_token])}

Rails3 and Rspec2 controller testing with a namespace

I'm trying to test a controller with a name space, following is my controller (/admin/sites_controller.rb):
class Admin::SitesController < AdminController
def create
#site = Site.new(params[:site])
respond_to do |format|
if #site.save
format.html { redirect_to(#site, :notice => 'Site was successfully created.') }
format.xml { render :xml => #site, :status => :created, :location => #site }
else
format.html { render :action => "new" }
format.xml { render :xml => #site.errors, :status => :unprocessable_entity }
end
end
end
end
and following is my routes.rb file
namespace :admin do
resources :sites
end
I'm using rspec2 to test my controller and following is my controller spec
describe Admin::SitesController do
describe "POST create" do
describe "with valid params" do
it "creates a new Site" do
expect {
post :create, :site => valid_attributes
}.to change(Site, :count).by(1)
end
end
end
end
But when I run the spec it gives me the following routing error
Admin::SitesController POST create with valid params creates a new Site
Failure/Error: post :create, :site => valid_attributes
NoMethodError:
undefined method `site_url' for #<Admin::SitesController:0xb5fbe6d0>
# ./app/controllers/admin/sites_controller.rb:47:in `create'
# ./app/controllers/admin/sites_controller.rb:45:in `create'
# ./spec/controllers/admin/sites_controller_spec.rb:78
# ./spec/controllers/admin/sites_controller_spec.rb:77
I guess its because of the 'admin' name space I'm using, but how can I fix that?
I'm using
Rails3
Rspec2
Linux
When you namespace the route, you're creating URL and path helpers that look like this:
HTTP Verb Path action helper
GET /admin/sites index admin_sites_path
GET /admin/sites/new new new_admin_site_path
POST /admin/sites create admin_sites_path
GET /admin/sites/:id show admin_site_path(:id)
GET /admin/sites/:id/edit edit edit_admin_site_path(:id)
PUT /admin/sites/:id update admin_site_path(:id)
DELETE /admin/sites/:id destroy admin_site_path(:id)
So you can either use those directly in your code (i.e. redirect_to admin_site_path(#site) ), or you can do something like:
redirect_to([:admin, #site])

Rails 3.1 respond_to :html with :except

I have the following in my controller:
respond_to :html, :except => :some_action
respond_to :json, :xml
If you hit the :some_action route in a browser (tested with Chrome), you get a 406 Not Acceptable response back. Is there a way to "catch" this in Rails and do something else (like a redirect)?
Additionally, I'm trying to avoid using the block form of respond_to. I'm just curious if there is some way to handle this case.
Check this out: http://ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with
There's a bit about action overriding:
class UsersController < ApplicationController::Base
respond_to :html, :xml, :json
# Override html format since we want to redirect to a different page,
# not just serve back the new resource
def create
#user = User.create(params[:user])
respond_with(#user) do |format|
format.html { redirect_to users_path }
end
end
end