What route to use to link to resource creator? - ruby-on-rails

My goal is to link the <%= #thing.user.username %> to the user's profile. I know it's something like:
<%= link_to #thing.user.username, %>
But what goes after the comma?
I can currently navigate to a user by going to "localhost:3000/users/UserNameHere". How do I link to that page dynamically?
Each of my Things has a line showing what user posted it. Here is how Things are displayed:
<div class='row'>
<div class='col-md-offset-2 col-md-8'>
<div class='panel panel-default'>
<div class='panel-heading text-center'>
<%= image_tag #thing.image.url(:medium) %>
</div>
<div class='panel-body'>
<p>
<strong><%= #thing.title %></strong>
</p>
<p>
<%= #thing.description %>
</p>
<p>
<%= #thing.user.username %>
</p>
<% if #thing.user == current_user %>
<%= link_to edit_thing_path(#thing) do %>
<span class='glyphicon glyphicon-edit'></span>
<% end %>
<% end %>
</div>
</div>
</div>
Here is my UsersController:
class UsersController < ApplicationController
def show
#user = User.find_by_id(params[:id])
end
end
Here are my routes:
Stynyl::Application.routes.draw do
resources :things
devise_for :users
get '/about', to: 'pages#about'
root 'things#index'
get 'users/:username' => "users#show"
end
Here is my rake routes output:
Prefix Verb URI Pattern Controller#Action
things GET /things(.:format) things#index
POST /things(.:format) things#create
new_thing GET /things/new(.:format) things#new
edit_thing GET /things/:id/edit(.:format) things#edit
thing GET /things/:id(.:format) things#show
PATCH /things/:id(.:format) things#update
PUT /things/:id(.:format) things#update
DELETE /things/:id(.:format) things#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
about GET /about(.:format) pages#about
root GET / things#index
GET /users/:username(.:format) users#show

You should stick to REST conventions in Rails, so use resources.
Replace:
get 'users/:username' => "users#show"
with:
resources :users, only: [:show]
then:
<%= link_to #thing.user.username, user_path(#thing.user.username) %>
or:
<%= link_to #thing.user.username, #thing.user %>
#and in model
def to_param
username
end
And replace params[:username] with params[:id] in your action.

Related

Nested routes with polymorphic association

I'm trying to implement the act_as_votable gem in my rails application. I got it to work on the blogs model, but the comments model is where I'm stuck. I get undefined methodlike_comment_path'` when I try to run it, and it's because there are no routes being generated like there are for the blog.
Here is the routes file:
resources :blogs do
member do
put 'like', to: 'blogs#upvote'
put 'dislike', to: 'blogs#downvote'
end
resources :comments
member do
put 'like', to: 'comments#upvote'
put 'dislike', to: 'comments#downvote'
end
end
On the blog index, I am able to call the blog like path just fine.
<div class="btn-group">
<%= link_to like_blog_path(blog), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Upvote
<%= blog.get_upvotes.size %>
<% end %>
<%= link_to dislike_blog_path(blog), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-down"></span>
Downvote
<%= blog.get_downvotes.size %>
<% end %>
</div>
I run into trouble, though, with the comment part.
<div class="btn-group">
<%= link_to like_comment_path(#commentable, comment), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-up"></span>
Upvote
<%= comment.get_upvotes.size %>
<% end %>
<%= link_to dislike_comment_path(#commentable, comment), method: :put, class: "btn btn-default btn-sm" do %>
<span class="glyphicon glyphicon-chevron-down"></span>
Downvote
<%= comment.get_downvotes.size %>
<% end %>
</div>
When I run rake routes, nothing for the comments comes up.
Prefix Verb URI Pattern Controller#Action
root GET / glips#index
pages_home GET /pages/home(.:format) pages#home
pages_about GET /pages/about(.:format) pages#about
pages_contact GET /pages/contact(.:format) pages#contact
tag GET /tags/:tag(.:format) glips#index
new_user_session GET /login(.:format) devise/sessions#new
user_session POST /login(.:format) devise/sessions#create
destroy_user_session DELETE /logout(.:format) devise/sessions#destroy
new_user_password GET /password/new(.:format) devise/passwords#new
edit_user_password GET /password/edit(.:format) devise/passwords#edit
user_password PATCH /password(.:format) devise/passwords#update
PUT /password(.:format) devise/passwords#update
POST /password(.:format) devise/passwords#create
cancel_user_registration GET /cancel(.:format) devise/registrations#cancel
new_user_registration GET /register(.:format) devise/registrations#new
edit_user_registration GET /edit(.:format) devise/registrations#edit
user_registration PATCH / devise/registrations#update
PUT / devise/registrations#update
DELETE / devise/registrations#destroy
POST / devise/registrations#create
like_blog PUT /blogs/:id/like(.:format) blogs#upvote
dislike_blog PUT /blogs/:id/dislike(.:format) blogs#downvote
blog_comments GET /blogs/:blog_id/comments(.:format) comments#index
POST /blogs/:blog_id/comments(.:format) comments#create
new_blog_comment GET /blogs/:blog_id/comments/new(.:format) comments#new
edit_blog_comment GET /blogs/:blog_id/comments/:id/edit(.:format) comments#edit
blog_comment GET /blogs/:blog_id/comments/:id(.:format) comments#show
PATCH /blogs/:blog_id/comments/:id(.:format) comments#update
PUT /blogs/:blog_id/comments/:id(.:format) comments#update
DELETE /blogs/:blog_id/comments/:id(.:format) comments#destroy
PUT /blogs/:id/like(.:format) comments#upvote
PUT /blogs/:id/dislike(.:format) comments#downvote
blogs GET /blogs(.:format) blogs#index
POST /blogs(.:format) blogs#create
new_blog GET /blogs/new(.:format) blogs#new
edit_blog GET /blogs/:id/edit(.:format) blogs#edit
blog GET /blogs/:id(.:format) blogs#show
PATCH /blogs/:id(.:format) blogs#update
PUT /blogs/:id(.:format) blogs#update
DELETE /blogs/:id(.:format) blogs#destroy
users GET /users(.:format) users#index
GET /users/:id(.:format) users#show
user GET /users/:id(.:format) users#show
I cannot figure out how to make the comment path work with the routes. What am I doing wrong?
Are you looking for nesting the :comments resource inside :blogs? Otherwise your routes should look like:
resources :blogs do
member do
put 'like', to: 'blogs#upvote'
put 'dislike', to: 'blogs#downvote'
end
end
resources :comments do
member do
put 'like', to: 'comments#upvote'
put 'dislike', to: 'comments#downvote'
end
end
(note you had a missing do at beginning of the :comments block which resulted in a weird block ending/nesting)

Routing error UsersController

I have a link_to that takes the users to their profile page. It used to work before but now I keep on getting a uninitialized constant UsersController.
Routes:
Rails.application.routes.draw do
resources :users
resources :questions
devise_for :users
root 'home#index'
get '/users/:id' => 'home#profile'
end
Index.html.erb:
<div class="row">
<div class="col-md-8">
<% if #questions.any? %>
<% #questions.each do |question| %>
<div class="well">
<div class="media">
<a class="pull-left">
<% if question.user.avatar.blank? %>
<img src="http://www.adtechnology.co.uk/images/UGM-default-user.png" style="width: 75px;">
<% else %>
<%= image_tag question.user.avatar, :style => "width:75px;" %>
<% end %>
</a>
<div class="media-body">
<h4 class="media-heading"><%= link_to question.title, question_path(question), :class => "ques" %></h4>
<p class="text-right">By <%= link_to question.user.username, question.user, :class => " bg" %></p> <!-- that's what's causing the error -->
<p class="text-muted"><%= truncate(question.description, :length => 50) %></p>
<ul class="list-inline navbar-right list-unstyled">
<li><span style="padding-right: 10px;" ><i class="fa fa-calendar"></i> asked <%= time_ago_in_words(question.created_at) %> ago </span></li>
</ul>
</div>
</div>
</div>
<% end %>
<% else %>
<p>No content yet</p>
<% end %>
Rake routes:
users_path GET /users(.:format) users#index
POST /users(.:format) users#create
new_user_path GET /users/new(.:format) users#new
edit_user_path GET /users/:id/edit(.:format) users#edit
user_path GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
questions_path GET /questions(.:format) questions#index
POST /questions(.:format) questions#create
new_question_path GET /questions/new(.:format) questions#new
edit_question_path GET /questions/:id/edit(.:format) questions#edit
question_path GET /questions/:id(.:format) questions#show
PATCH /questions/:id(.:format) questions#update
PUT /questions/:id(.:format) questions#update
DELETE /questions/:id(.:format) questions#destroy
new_user_session_path GET /users/sign_in(.:format) devise/sessions#new
user_session_path POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session_path DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password_path POST /users/password(.:format) devise/passwords#create
new_user_password_path GET /users/password/new(.:format) devise/passwords#new
edit_user_password_path GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration_path GET /users/cancel(.:format) devise/registrations#cancel
user_registration_path POST /users(.:format) devise/registrations#create
new_user_registration_path GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration_path GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root_path GET / home#index
GET /users/:id(.:format) home#profile
As I said before, I don't really know what's causing the error. It was working properly yesterday and I didn't do any changes at all.
You should use <%= link_to home_profile(question.user.id) %>.
Assuming question.user.id get's user's corresponding id.
Acess users's id in Profile controller by params[:id].
I fixed it by putting the resources at the bottom instead:
Rails.application.routes.draw do
devise_for :users
root 'home#index'
get '/users/:id' => 'home#profile'
resources :users
resources :questions
end
My guess is that it was overriding the devise_for :users

Rails Devise Engine Sign_out link Error

I've installed devise on my engine and applied the following in my application.html.erb file:
<div id="user_nav">
<% if user_signed_in? %>
Signed in as <%= current_user.email %>. This cannot be cheese?
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
<% else %>
<%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
<% end %>
</div>
It shows No route matches "/users/sign_out" and it shows error for
<%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
Error Message NameError in Devise::Sessions#new
undefined local variable or method `destroy_user_session_path' for #<#<Class:0x007fb4da2e9618>:0x007fb4da2db9a0>
Rake Routes Result
Routes for Fd::Engine:
users_auth_google_oauth2_callback GET /users/auth/google_oauth2/callback(.:format) fd/omniauth_callbacks#google_oauth2
fd_test_index GET /fd/test/index(.:format) fd/fd/test#index
fd_omniauth_callbacks_google_oauth2 GET /fd/omniauth_callbacks/google_oauth2(.:format) fd/fd/omniauth_callbacks#google_oauth2
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) omniauth_callbacks#passthru {:provider=>/google_oauth2/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:google_oauth2)
fd_auth_index GET /fd/auth/index(.:format) fd/fd/auth#index
root GET / fd/auth#index
omniauth_callbacks_verify_otp GET /omniauth_callbacks/verify_otp(.:format) fd/omniauth_callbacks#verify_otp
omniauth_callbacks_delete_session GET /omniauth_callbacks/delete_session(.:format) fd/omniauth_callbacks#sign_out
Engine routes:
Fd::Engine.routes.draw do
devise_for :users,:controllers => { :omniauth_callbacks => "omniauth_callbacks" }, :class_name => "Fd::User", module: :devise
end
You Integrated OmniAuth in Devise, so if user gives correct credentials devise will create session , From your question i understand session is successfully created so if you want clear session just create a action in a controller(where you start session) and give
redirect_to "/users/sign_out"
or
try
redirect_to destroy_user_session_path
I hope this will work
Try this :
<%= link_to "Sign out", destroy_user_session_path, :method => :get %>
And make sure that you have below line in your config/initializers/devise.rb
config.sign_out_via = :get

undefined method `username' for nil:NilClass when signing up and signing in

Whenever I try to log in and sign up, I am hit with this error:
undefined method `username' for nil:NilClass
on these two lines:
<strong><%= #user.username %></strong> <br>
<strong><%= #user.name %></strong>
Here is the full error from the server's output:
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'sign_in' LIMIT 1
Rendered users/show.html.erb within layouts/application (2.1ms)
Completed 500 Internal Server Error in 7ms
ActionView::Template::Error (undefined method `username' for nil:NilClass):
1: <strong><%= #user.username %></strong> <br>
2: <strong><%= #user.name %></strong>
3: <%= debug #user %>
4:
app/views/users/show.html.erb:1:in `_app_views_users_show_html_erb__1133891108745893964_2164088020'
Here are my routes:
Stynyl::Application.routes.draw do
resources :things
resources :users, only: [:show]
devise_for :users
get '/about', to: 'pages#about'
root 'things#index'
end
Here is my user show view
<strong><%= #user.username %></strong> <br>
<strong><%= #user.name %></strong>
<div id="things" class="transitions-enabled">
<% #user.things.each do |thing| %>
<div class='panel panel default'>
<div class="box">
<%= link_to image_tag(thing.image.url(:medium)), thing %>
<div class='panel-body'>
<strong><p><%= thing.title %></p></strong>
<p><%= thing.description %></p>
By <%= link_to thing.user.username, thing.user %>
<% if thing.user == current_user %>
<%= link_to edit_thing_path(thing) do %>
<span class='glyphicon glyphicon-edit'></span> Edit
<% end %>
<%= link_to thing_path(thing), method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class='glyphicon glyphicon-trash'></span> Delete
<% end %>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
Here is my UsersController file:
class UsersController < ApplicationController
def show
#user = User.find_by_username(params[:id])
end
end
Output of rake routes:
Prefix Verb URI Pattern Controller#Action
things GET /things(.:format) things#index
POST /things(.:format) things#create
new_thing GET /things/new(.:format) things#new
edit_thing GET /things/:id/edit(.:format) things#edit
thing GET /things/:id(.:format) things#show
PATCH /things/:id(.:format) things#update
PUT /things/:id(.:format) things#update
DELETE /things/:id(.:format) things#destroy
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
about GET /about(.:format) pages#about
root GET / things#index
Edits
I also noticed that when I delete all of the code from the User show view, I can get to the signup and login pages, but they are blank. Can we safely guarantee that the problem is in the view? I'm so perplexed at how something in the show view can affect the ability to sign in and sign up!
I have also observed that when I add content to the users show view, it appears on the sign up and login pages. What on earth is going on?
The reason is because of a conflict in your routes. When matching a request to a route, Rails will go through your routes sequentially. But your order shows:
user GET /users/:id(.:format) users#show
new_user_session GET /users/sign_in(.:format) devise/sessions#new
And so Rails is passing sign_in as the :id parameter to your user show method, instead of being caught by devise's new_user_session_path. Changing the order will fix the problem.
TL:DR; devise_for :users should be declared before resources :users.

No route matches [POST]

on my app i have this
i'm trying to create a car of a previously registered user
but i got the error (tittle post)
this is my carcontroller
class CarController < ApplicationController
def new
#car = Car.new
end
def create
#user = User.find(params[:user_id])
#car = #user.car.create(params[:car])
redirect_to user_path(#user)
end
end
this is my route.rb
Estaciones::Application.routes.draw do
devise_for :users
root :to => "user#index"
resources :user do
resources :cars
end
get "user/new"
post "user/create"
get "user/:id" => "User#show"
get "user/:user_id/car/new"
and this is part of my html.erb
<div class="container">
<h1>new user registered</h1>
<p>
<strong>name:</strong>
<%= #user.name %>
</p>
<p>
<strong>email:</strong>
<%= #user.email %>
</p>
<h2>new car registration</h2>
<%= form_for([#user, #user.car.build]) do |f| %>
<p>
<%= f.label :brand %><br />
<%= f.text_field :brand %>
</p>
<p>
<%= f.label :color %><br />
<%= f.text_field :color %>
</p>
<p>
<%= f.label :model %><br />
<%= f.text_field :model %>
</p>
<p>
<%= f.label :year %><br />
<%= f.text_field :year %>
</p>
<p>
<%= f.submit "Create new car"%>
</p>
<% end %>
</div>
when i submit the creation of the new car i got the next error
No route matches [POST] "/user/1/cars"
any idea??
also my routes:
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / user#index
user_cars GET /user/:user_id/cars(.:format) cars#index
POST /user/:user_id/cars(.:format) cars#create
new_user_car GET /user/:user_id/cars/new(.:format) cars#new
edit_user_car GET /user/:user_id/cars/:id/edit(.:format) cars#edit
user_car GET /user/:user_id/cars/:id(.:format) cars#show
PUT /user/:user_id/cars/:id(.:format) cars#update
DELETE /user/:user_id/cars/:id(.:format) cars#destroy
user_index GET /user(.:format) user#index
POST /user(.:format) user#create
new_user GET /user/new(.:format) user#new
edit_user GET /user/:id/edit(.:format) user#edit
user GET /user/:id(.:format) user#show
PUT /user/:id(.:format) user#update
DELETE /user/:id(.:format) user#destroy
user_new GET /user/new(.:format) user#new
user_create POST /user/create(.:format) user#create
GET /user/:id(.:format) User#show
GET /user/:user_id/cars/new(.:format) car#new
You need CarsController not CarController

Resources