Link helper VS typing URL - ruby-on-rails

Something weird is happening and I don't know why.
When I use the helper <%= link_to "New game", new_game_path %>, my new game form does not submit.
But when I acesses the view typing the URL localhost:3000/games/new form works just well
Any idea how to solve that?
Thanks,
Here my rake routes
Prefix Verb URI Pattern Controller#Action
root GET / games#index
user_sessions GET /user_sessions(.:format) user_sessions#index
POST /user_sessions(.:format) user_sessions#create
new_user_session GET /user_sessions/new(.:format) user_sessions#new
edit_user_session GET /user_sessions/:id/edit(.:format) user_sessions#edit
user_session GET /user_sessions/:id(.:format) user_sessions#show
PATCH /user_sessions/:id(.:format) user_sessions#update
PUT /user_sessions/:id(.:format) user_sessions#update
DELETE /user_sessions/:id(.:format) user_sessions#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
delete_progress_progresses POST /progresses/delete_progress(.:format) progresses#delete_progress
progresses POST /progresses(.:format) progresses#create
search GET /search(.:format) games#search
game_levels GET /games/:game_id/levels(.:format) levels#index
POST /games/:game_id/levels(.:format) levels#create
new_game_level GET /games/:game_id/levels/new(.:format) levels#new
edit_game_level GET /games/:game_id/levels/:id/edit(.:format) levels#edit
game_level GET /games/:game_id/levels/:id(.:format) levels#show
PATCH /games/:game_id/levels/:id(.:format) levels#update
PUT /games/:game_id/levels/:id(.:format) levels#update
DELETE /games/:game_id/levels/:id(.:format) levels#destroy
insert_levels_game POST /games/:id/insert_levels(.:format) games#insert_levels
games GET /games(.:format) games#index
POST /games(.:format) games#create
new_game GET /games/new(.:format) games#new
edit_game GET /games/:id/edit(.:format) games#edit
game GET /games/:id(.:format) games#show
PATCH /games/:id(.:format) games#update
PUT /games/:id(.:format) games#update
DELETE /games/:id(.:format) games#destroy
login GET /login(.:format) user_sessions#new
logout POST /logout(.:format) user_sessions#destroy
My route file
Rails.application.routes.draw do
root :to => 'games#index'
resources :user_sessions
resources :users
resources :progresses, :only => :create do
collection do
post 'delete_progress'
end
end
get 'search' => 'games#search'
resources :games do
resources :levels
member do
post 'insert_levels'
end
end
get 'login' => 'user_sessions#new', :as => :login
post 'logout' => 'user_sessions#destroy', :as => :logout
end

Sure, you can use string as relative URL. This will never crash since rails will not try to resolve your routes building it. My guess is, that you might have a typo of some sort.
There is no reason why this wouldn't work. I have searched your git app for "new_game_path" but could not find a single example where you use this code.
I have only found < a href="/games/new">New game</a> in your layout.
Replace it with <%= link_to 'New Game', new_game_path %> this works in your app. I have just tested it.
If you intend to use internationalization at some point, you should avoid standard HTML links. They will not keep your locale persistent.

form
You mention that your "form does not submit"
This is not a problem with your link_to - it's an issue with your form; they are two different issues:
--
link_to
link_to takes you to a new page. It's a helper method to help create the equivalent of Your text
This means that if you're sending requests to your new action, it should not matter how the users get there - only how the action is rendered.
The typical case for a form is as follows:
#app/views/games/new.html.erb
<%= form_for #game do |f| %>
<%= f.text_field :attribute %>
<%= f.submit "test" %>
<% end %>
#app/controllers/games_controller.rb
Class GamesController < ApplicationController
def new
#game = Game.new
end
end
--
Fix
When you mention your new game form does not submit, that's an issue with your form itself. This could be due to a number of reasons, but typically with the way in which you're rendering the form
To fix this, you'll need to detail how you're rendering your form & how you'd like it to submit
Update
Having read your updated comments, if the form works when you send the requests to the "naked" url, the issue may not be with the form itself.
As a rule of thumb, you'll always want to use the Rails helpers when defining links etc. In your application layout, I found that you posted "pure" HTML to create a link. This is bad because if the Rails syntax changes, or your routes change, your application won't update correctly.

Related

Why does my controller keep routing my link_to toward "show" action? Rails 4

So I am pretty stumped. I am new to Ruby on Rails (I am using Rails 4) and I have been trying to figure out for the last two days why my link_to tag keeps routing my login action to show instead. I removed the show action from my controller and even deleted show.html.erb and yet Rails remains persistent in trying to route it to a show action that no longer exists.
I removed all my redirect_to functions, and the link_to I create takes me to the correct page localhost:8000/users/login but now displays the error Unknown Action: The action 'show' could not be found for UsersController.
I have read up other SO questions that were similar, and some suggest that it may be an issue with jquery_ujs, which I removed from my file to see if it was the problem, but I still ended up with the same result.
The files in my views directory are as follows:
views
users
new.html.erb
login.html.erb
Here's what my code looks like:
The link_to in users/new (new.html.erb)
<li><%= link_to "Login", users_login_path %></li>
routes.rb
resources :users
root 'users#new'
get 'users/create'
get 'users/login'
users_controller.rb
class UsersController < ApplicationController
def new
end
def create
#user = User.create(:username => params[:username], :password => params[:password])
#user.save
#users = User.all
end
def login
#message = "Success"
end
end #end class
login.html.erb (Just testing an output here to see if it ever gets to this page)
<h3><%= #message %></h3>
Output of rake routes command
Prefix Verb URI Pattern Controller#Action
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / users#new
users_create GET /users/create(.:format) users#create
users_login GET /users/login(.:format) users#login
I figured out what the problem was:
I needed to remove resources :users from the routes.rb file.
Everything is working as expected now. After doing a little bit of research it seems that the problem with having resources :users in there is that when browsers try to access the page they try to perform a command by using an HTTP method, which is either GET, POST, PUT, DELETE, or PATCH.
When the page looks for an incoming command which in this case was GET /users/login, it tries to map it to a controller action. If the first matching route is resources :users, it will send it to the show action.
It seems that this is due to the default CRUD system Rails uses where each HTTP method represents a CRUD action (correct me if I am wrong):
GET is show
POST is create
DELETE is destroy
PATCH is update
I got most of this research from Rails Routing from the Outside In, Section 2.1.

Rails routing when nesting resources

I'm trying to figure out how to specify the route I'm trying to use but I keep getting routing errors. Can someone please point out where I'm going wrong and maybe explain what a better way to do this might be?
I'm working with these (nested) resources:
resources :users do
resources :playlists
end
Models:
class User < ActiveRecord::Base
has_many :playlists
end
class Playlist < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
end
Now I'm trying to link to a user's playlists inside the user/show.html.erb file:
<p>
<%= link_to "Playlists", user_playlists_path(#playlist)%></p>
</p>
Which brings me to a Playlists page (/users/1/playlists) successfully but when I try adding a new playlist for this user, I get the following error:
Showing /app/views/playlists/_form.html.erb where line #1 raised:
undefined method `playlists_path' for #<#<Class:0x0000000335c688>:0x00000003d0b238>
This is line #1:
<%= form_for(#playlist) do |f| %>
This is what I get for rake routes if that helps at all:
Prefix Verb URI Pattern Controller#Action
user_playlists GET /users/:user_id/playlists(.:format) playlists#index
POST /users/:user_id/playlists(.:format) playlists#create
new_user_playlist GET /users/:user_id/playlists/new(.:format) playlists#new
edit_user_playlist GET /users/:user_id/playlists/:id/edit(.:format) playlists#edit
user_playlist GET /users/:user_id/playlists/:id(.:format) playlists#show
PATCH /users/:user_id/playlists/:id(.:format) playlists#update
PUT /users/:user_id/playlists/:id(.:format) playlists#update
DELETE /users/:user_id/playlists/:id(.:format) playlists#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / default_pages#home
signup GET /signup(.:format) users#new
signin GET /signin(.:format) users#signin
The errors:
undefined method `playlists_path' for #<#<Class:0x0000000335c688>
and
user_playlist GET /users/:user_id/playlists/:id(.:format)
Gives a clear reason of the error you have.
<%= form_for(#playlist) do|f| %>
should be
<%= form_for([#user, #playlist]) do|f| %>
Or current_user, what is important is you need to pass the user object.
Explanation :
If you have noticed in a update action (taking that you redirect to a show page after you update) instead of redirect_to user_path(#user) we can do just redirect_to #user, from which Rails infers that you are redirecting to the show path of user.
It is a similar situation here, similarly if you are having a form_for for the playlist and you pass only #playlist instead of [#user, #playlist] then it woud try to find new_playlist_path, which isn't in your route and will show an error.
This is a short gist on how you might do it.
This:
<%= form_for(#playlist) do |f| %>
Should be This:
<%= form_for [#user, #playlist] do |f| %>
note the square brackets

NoMethodError new to Rails

Ive been following some rails guides and im trying to now implement something on my own for a project im doing and have hit a snag at the first hurdle
I get this error when trying to load the page
ActionController::UrlGenerationError in StepOne#login
Showing /Users/rogan/Sites/authImp/app/views/step_one/login.html.erb where line #3 raised:
No route matches {:action=>"show", :controller=>"step_one"} missing required keys: [:id]
Extracted source (around line #3):
<%= form_for url: step_one_path do %>
form stuff...
then my step_one_controller.rb
class StepOneController < ApplicationController
def new
end
def create
user = User.authenticate(params[:email], params[:password])
if user
pincode = generatePin
puts "one use pin.#{pincode}"
redirect_to "step_two"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
end
this was adapter from a login system i saw in a guide that used SessionsController.rb and form_for url: sessions_path
but my simple changes seem to have broke it, i've looked at my routes as well and they all seem to be in order
edit: heres is my routes
edit edit: changed everything to step_one and to removed the 's' as suggested, I now get
NoMethodError in StepOne#login
undefined method `model_name' for Hash:Class
<%= form_for url: step_one_path do %>
so from one problem to another!
AuthImp::Application.routes.draw do
resources :users
resources :sessions
resource :step_one
get "users/:id" => "users#show"
get "sign_up" => "users#new"
get "log_in" => "step_one#login"
get "step_two" => "sessions#new"
get "log_out" => "sessions#destroy", :as => "log_out"
then my rake routes is as follows
root to: "welcome#index"
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions GET /sessions(.:format) sessions#index
POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
edit_session GET /sessions/:id/edit(.:format) sessions#edit
session GET /sessions/:id(.:format) sessions#show
PATCH /sessions/:id(.:format) sessions#update
PUT /sessions/:id(.:format) sessions#update
DELETE /sessions/:id(.:format) sessions#destroy
step_one POST /step_one(.:format) step_ones#create
new_step_one GET /step_one/new(.:format) step_ones#new
edit_step_one GET /step_one/edit(.:format) step_ones#edit
GET /step_one(.:format) step_ones#show
PATCH /step_one(.:format) step_ones#update
PUT /step_one(.:format) step_ones#update
DELETE /step_one(.:format) step_ones#destroy
GET /users/:id(.:format) users#show
sign_up GET /sign_up(.:format) users#new
log_in GET /log_in(.:format) step_one#login
step_two GET /step_two(.:format) sessions#new
log_out GET /log_out(.:format) sessions#destroy
root GET / welcome#index
your problem is in the naming I think, resources :step_one assumes that you define the StepOnesController (plural), not StepOneController
So, you should either rename your controller or use resource :step_one route (without the s at the end)
It looks like Rails is expecting you to pass in an id to your step_one_path, so the form_for should look like this:
<%= form_for url: step_one_path(#user.id) do %>
Where #user.id would be the id of the user that the form is associated with. Hope that helps. If not, please include your routes.rb file.
<%= form_tag step_one_path do |f| %>
was the form tag necessary, i was going about it wrong
thanks for all the help

Why am I getting "No route matches [GET]" on a "delete" request? Ruby on Rails

When I try to delete the content of a communityfeed_item/micropost I get the following error:
Routing Error
No route matches [GET] "/microposts/45"
Try running rake routes for more information on available routes.
I check my routes and see a delete and post, which is all I really need to function, yet I keep receiving a "get" error.
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
locations GET /locations(.:format) locations#index
POST /locations(.:format) locations#create
new_location GET /locations/new(.:format) locations#new
edit_location GET /locations/:id/edit(.:format) locations#edit
location GET /locations/:id(.:format) locations#show
PUT /locations/:id(.:format) locations#update
DELETE /locations/:id(.:format) locations#destroy
communitys GET /communitys(.:format) communitys#index
POST /communitys(.:format) communitys#create
new_community GET /communitys/new(.:format) communitys#new
edit_community GET /communitys/:id/edit(.:format) communitys#edit
community GET /communitys/:id(.:format) communitys#show
PUT /communitys/:id(.:format) communitys#update
DELETE /communitys/:id(.:format) communitys#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
microposts POST /microposts(.:format) microposts#create
micropost DELETE /microposts/:id(.:format) microposts#destroy
/communitys(.:format) communitys#index
/users(.:format) users#index
profile_info /profile/info(.:format) users#info
join /join(.:format) users#new
login /login(.:format) sessions#new
logout DELETE /logout(.:format) sessions#destroy
root / static_pages#home
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
/posts(.:format) static_pages#posts
meetups /meetups(.:format) static_pages#meetups
chat /chat(.:format) static_pages#chat
groups /groups(.:format) static_pages#groups
web /web(.:format) static_pages#web
profile /profile(.:format) static_pages#profile
My view code in shared/_communityfeed_item.html.erb contains a delete method:
<% if current_user?(communityfeed_item.user) %>
<%= link_to "delete", communityfeed_item, method: :delete,
confirm: "You sure?",
title: communityfeed_item.content %>
<% end %>
Yet, when I click delete I am sending a "get" request for some reason, which is giving a routing error. Does anyone know why this might be happening?
This is nutty, even when on my profile page where I use this delete request:
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
confirm: "You sure?",
title: micropost.content %>
<% end %>
I still get the no route matches [GET]!
Even weirder, this is the HTML getting rendered:
​delete​​
​delete​​
etc. despite this being the embedded ruby:
<% if current_user?(communityfeed_item.user) %>
<%= link_to "delete", communityfeed_item, method: :delete,
confirm: "You sure?",
title: communityfeed_item.content %>
<% end %>
In the routes.rb:
Meetumea::Application.routes.draw do
resources :comments
resources :posts
resources :locations
resources :communitys
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy]
match '/communitys', to: "communitys#index"
match '/users', to: "users#index"
match '/profile/info', to: "users#info"
match '/join', to: "users#new"
match '/login', to: 'sessions#new'
match '/logout', to: 'sessions#destroy', via: :delete
root to: "static_pages#home"
match '/help', to: "static_pages#help"
match '/about', to: "static_pages#about"
match '/contact', to: "static_pages#contact"
match '/posts', to: "static_pages#posts"
match '/meetups', to: "static_pages#meetups"
match '/chat', to: "static_pages#chat"
match '/groups', to: "static_pages#groups"
match '/web', to: "static_pages#web"
match '/profile', to: "static_pages#profile"
end
Sounds like there's a problem with your unobtrusive JavaScript included in your page.
In your master layout (at layouts/application.erb.html or something thereof), do you see javascript_include_tag :application somewhere? That'll point to app/assets/javascripts/application.js. You should see this in that file.
//= require jquery
//= require jquery_ujs
The last line ensures the necessary libraries for unobtrusive JavaScript are loading with the page request.
Then in your Gemfile, you should have gem "jquery-rails". You'll want to make sure that if it's been added recently, run bundle install inside your project directory from the command line to make sure it's installed.
Do you see anything like that all? You won't see anything like rails.js loaded, I think, as that'll be with older versions of jquery-ujs or jquery-rails. When you view the source of the rendered page, you should see a data-method attribute on the delete link if the JavaScript libraries are included on the page and running properly.
I'm willing to bet — dollars to donuts — that this is a JavaScript issue. Rails uses the jquery_ujs script file to ensure "delete" links use the DELETE HTTP verb, which is similar to a POST action, but only used when deleting resources. Otherwise, the link ends up as a plain old GET action (if the JavaScript isn't loading right). jquery_ujs is responsible for emitting new link tags with things like data-method and data-confirm based on what it's given by the ERB renderer (somebody can correct me if I'm wrong about how this works; I very well could be).
Based on what your link tag is getting rendered as, I'd say something isn't right with the unobtrusive JavaScript. This describes what should be happening (specifically, the part about sending :method => symbol). At this point, I'm not sure what to tell you; something is definitely up with your JavaScript. Is it even loading? If you're using Chrome or Safari, you can use the Scripts panel in the Web Inspector to see if the Rails Asset Pipeline is pulling in the necessary scripts (jquery.js and jquery_ujs.js); if you're using Firefox, then Firebug is the way to go. Apart from that… I'm at a loss. Everything that's been stated here should work for you.
It's because of the call to wrap in views/static_pages/home.html.erb.
This does work:
<%= render 'shared/communityfeed' %>
This doesn't:
<%= wrap render 'shared/communityfeed' %>
It's because you are using sanitize in your wrap code:
It strips all attributes that aren't specifically allowed.
So for some reason in the views <%= wrap render #Microposts %> and <%= wrap render 'shared/communityfeed' %> were what was causing the trouble. When I removed 'wrap' everything started working fine.
The wrap code:
def wrap(content)
sanitize(raw(content.split.map{ |s| wrap_long_string(s) }.join(' ')))
end
def wrap_long_string(text, max_width = 50)
zero_width_space = "​"
regex = /.{1,#{max_width}}/
(text.length < max_width) ? text :
text.scan(regex).join(zero_width_space)
end
See: https://stackoverflow.com/questions/10326180/why-is-rails-not-rendering-method-delete-into-html#comment13310733_10326180

Rails, trouble in a form trying to use the put http method

<% form_ tag user_path(#user), :method => :put do %>
That's my form, so I want it to access the update method of my UsersController, I set the map.resources :users , and the RESTful paths generated:
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create",:controller=>"users"}
new_ user GET /users/new(.:format) {:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"}
So I try to send to user_path(#user) using the PUT HTTP method and it comes back with:
Unknown action
No action responded to 1. Actions: create, destroy, edit, index, logged?, new, show and update
So obviously I don't know how to make this work, so thanks in advance.
If you're using RESTful resources (and you should be), try using form_for not form_tag ... with the full setup like this:
<% form_for :user, #user, :url=>user_path(#user), :html=>{:method=>:put} do |f| %>
#this scopes the form elements to the #user object, eg.
<%= f.text_field :first_name %>
<% end %>
Check out the API docs for more.
Too late to answer, but check this out http://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-put-or-delete-methods-work
Not all browsers support PUT so you use POST with a hidden input stating that the method is PUT
Just a shot in the dark, but have you tried this?
<% form_tag :url=>user_path(#user), :html=>{:method=>:put} do %>
Did you restart your server? My routes.rb never gets reloaded correctly if I update it while the server is running.
I ran into this exact problem when trying to use a tableless model (Rails model without database).
After some quick digging into actionpack's form_helper.rb I found a solution. Add this to your model:
def new_record?; false; end
In my case my model is always built from scratch so this was necessary to "trick" Rails into treating it as an existing object, and thus doing a PUT rather than a POST.

Resources