I have 1000 Tips and 95 Users in my PostgreSQL database and I want the user to be able to create a new Tip and be taken to the show page where they can see the tip name and description along with author information.
However, I am getting the error "Couldn't find User with 'id'=1003" raised on this line #author_firstname = User.find(params[:id]).first_name. I'm not sure why it's assigning the user id to the new Tip id, but I want the User's id to be tied to the Tip instead of the Tip id.
Here is my Tips Controller:
class TipsController < ApplicationController
def index
#tips = Tip.all
end
def new
#tip = Tip.new
end
def create
#tip = Tip.create(tip_params)
redirect_to "/tips/#{#tip.id}"
end
def show
#tip = Tip.find(params[:id])
#author_firstname = User.find(params[:id]).first_name
#author_lastname = User.find(params[:id]).last_name
end
private
def tip_params
params.require(:tip).permit(:name, :description)
end
end
And some of my routes:
get '/users/new', to: 'users#new'
post '/users', to: 'users#create'
get 'users/:id', to: 'users#show', as: 'user'
get 'users/:id/edit', to: 'users#edit'
patch 'users/:id', to: 'users#update'
get '/places/:id', to: 'places#show'
get '/tips/new', to: 'tips#new'
post '/tips', to: 'tips#create'
get '/tips/:id', to: 'tips#show', as: 'tip'
Inside the TipsController, params[:id] will give you the id of the tip NOT the id of the user.
As, your tip belongs_to user, so you should be able to get the user using this: #tip.user
So, your show method can be:
def show
#tip = Tip.find(params[:id])
#author_firstname = #tip.user.first_name
#author_lastname = #tip.user.last_name
end
It looks like when you save your tip, you didn't save the current_user id in tip by putting #tip.user_id = current_user.id in your create method.
class TipsController < ApplicationController
def index
#tips = Tip.all
end
def new
#tip = Tip.new
end
def create
#tip = Tip.new(tip_params)
#tip.user_id = current_user.id
if #tip.save
redirect_to "/tips/#{#tip.id}"
else
render :new
end
end
def show
#tip = Tip.find(params[:id])
#author_firstname = #tip.user.first_name
#author_lastname = #tip.user.last_name
end
private
def tip_params
params.require(:tip).permit(:name, :description, :user_id)
end
end
Next, you can get user name by calling #tip.user.first_name. I hope this help you.
Related
I have a small game in which after the game is over the user is linked to a view that displays a leader board of all users and their scores. To do this I have treated the link as an update action so that the users score can be updated after the game is over, however, upon clicking the link I get an error saying "param is missing or the value is empty: user". I am also wondering if this is being caused because there is no form to be filled simply a variable being updated.
Controllers:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to '/play'
else
render '/'
end
end
def update
#user = User.find(current_user)
if #user.update(user_params)
redirect_to '/leaderboard'
else
render '/play'
end
end
private
def user_params
params.require(:user).permit(:nick_name, :score)
end
end
class ScoresController < ApplicationController
before_action :require_user, only: [:index]
def index
#user = User.find(current_user)
#score = #user.score
#score = 0
end
def leaderboard
#users = User.all
end
end
View-link:
<div class="game-over"><%= link_to 'Game Over', "/update", :style => 'text-decoration:none; color:white;' %></div>
Routes:
Rails.application.routes.draw do
root 'users#new', as: :users
post '/' => 'users#create'
get '/logout' => 'sessions#destroy'
get '/play' => 'scores#index', as: :user
get '/update' => 'users#update'
get '/leaderboard' => 'scores#leaderboard'
user has to be present in the request params because you required it in user_params. You can change link_to to use query parameters as follows:
link_to "Refresh", {controller: 'users', action: 'update', nick_name: "#{user.nick_name}", score: "#{get_score}"}, style: '...'
Or change update route to contain those parameters in the url.
# routes.rb
get '/update/:nick_name/:score' => 'users#update'
Tip: You probably should change it to PUT and use form instead, since update action alters state in the server.
Looks like whatever you are using to pass through your params to make the request is not properly nested under a user key.
In my show page I would like to change the route of a 'view more' button based on the value of a variable. For instance, if I'm looking at a building in Tampa Florida on the show page and I click 'view more', I want to go back to locations_tampa_path to see the full listing of buildings in Tampa again. However, I would like the path in the link to change based on the city of that particular building:
something like this: location_#{#location.city}_path
What is the best way to do this?
Thanks in advance for any help given.
My controller:
class LocationsController < ApplicationController
def index
#locations = Location.all
end
def new
#location = Location.new
end
def create
#location = Location.new(location_params)
if #location.save
flash[:notice] = "New location added"
redirect_to root_path
else
flash.now[:error] = 'Cannot send message'
render 'new'
end
end
def jacksonville
#locations = Location.where(:city => "Jacksonville")
end
def stpetersburg
#locations = Location.where(:city => "St. Petersburg")
end
def orlando
#locations = Location.where(:city => "Orlando")
end
def tampa
# #location = Location.find(params[:id])
#locations = Location.where(:city => "Tampa")
#photo = Photo.new
end
def show
#location = Location.find(params[:id])
#photo = Photo.new
end
private
def location_params
params.require(:location).permit(:name, :description, :address, :city, :featured)
end
end
Routes
get 'locations/tampa', to: 'locations#tampa'
get 'locations/jacksonville', to: 'locations#jacksonville'
get 'locations/orlando', to: 'locations#orlando'
get 'locations/st_petersburg', to: 'locations#stpetersburg'
resources :locations do
resources :photos, only: :create
end
You're repeating yourself in your controller where you don't need to. It seems like you want a parameterized route:
In your routes.rb:
get "locations/:location", to: 'locations#show_location', as: :location_path
Then, you can pass location as a parameter in your view/controller:
location_path(location: #location.city)
And you can have a simple show_location action in your LocationsController:
def show_location
#location = Location.find_by(city: params[:location])
#photo = Photo.new
if #location
render #location.city
end
end
I want to allow users to vote on posts without signing up, and have the vote instead tied to their ip address. I tried following this post but I need some more clarification. this is the error im getting from the posts_controller
undefined method `find_or_create_by_ip' for #
This is my code so far:
posts_controller:
def upvote
#post = Post.find (params[:id])
session[:voting_id] = request.remote_ip
upvote = session.find_or_create_by_ip(session[:voting_id])
#post.upvote
redirect_to :back
end
def downvote
#post = Post.find (params[:id])
session[:voting_id] = request.remote_ip
downvote = session.find_or_create_by_ip(session[:voting_id])
#post.downvote
redirect_to :back
end
session model:
class session < ActiveRecord::Base
acts_as_voter
request.remote_ip
end
routes.rb:
Rails.application.routes.draw do
get 'static_pages/home'
get 'static_pages/about'
resources :posts do
member do
put "like" , to: "posts#upvote"
put "dislike" , to: "posts#downvote"
end
end
In the other post someone said add an ip column to the sessions table. What exactly does that mean? I also saw somewhere that I would need to create a db table as well. do I? and how would I do that? Sorry about having to post this, put Im pretty new to this, so it would be great if it was spelled out better for me. Thanks!
If you are using Rails 4+ dynamic finders have been deprecated and extracted to a gem. The standard is now find_or_create_by or find_or_initialize_by.
def upvote
#post = Post.find (params[:id])
session[:voting_id] = request.remote_ip
upvote = Session.find_or_create_by(ip: session[:voting_id])
#post.upvote
redirect_to :back
end
def downvote
#post = Post.find (params[:id])
session[:voting_id] = request.remote_ip
downvote = Session.find_or_create_by(ip: session[:voting_id])
#post.downvote
redirect_to :back
end
class Session < ActiveRecord::Base
acts_as_voter
request.remote_ip
end
I´m new to Rails and can´t find any solution to my problem with my namespace I created.
The problem is that if I like to show all my rooms under localhost:3000/manage/ it does not work.
error: undefined method `title' for nil:NilClass.
If I try to show all my rooms under ../manage/rooms/ it is still not showing all rooms I created error: can´t find id... if I use an id e.g. ../manage/rooms/38 it is working. Hope someone can help me.
So here we go:
I created a namespace like:
routes.rb:
resources :manage
namespace :manage do
resources :rooms
end
Rake routes:
manage_index GET /manage(.:format) manage#index
POST /manage(.:format) manage#create
new_manage GET /manage/new(.:format) manage#new
edit_manage GET /manage/:id/edit(.:format) manage#edit
manage GET /manage/:id(.:format) manage#show
PATCH /manage/:id(.:format) manage#update
PUT /manage/:id(.:format) manage#update
DELETE /manage/:id(.:format) manage#destroy
manage_rooms GET /manage/rooms(.:format) manage/rooms#index
POST /manage/rooms(.:format) manage/rooms#create
new_manage_room GET /manage/rooms/new(.:format) manage/rooms#new
edit_manage_room GET /manage/rooms/:id/edit(.:format) manage/rooms#edit
manage_room GET /manage/rooms/:id(.:format) manage/rooms#show
PATCH /manage/rooms/:id(.:format) manage/rooms#update
PUT /manage/rooms/:id(.:format) manage/rooms#update
DELETE /manage/rooms/:id(.:format) manage/rooms#destroy
a controller under ../manage/rooms_controller.rb
class Manage::RoomsController < ApplicationController
def index
#rooms = Room.all
end
def new
#room = Room.new
end
def create
#ender text: params[:rooms].inspect
#render text: Rails.logger.info(params[:rooms].inspect)
#room = Room.new(room_params)
if #room.save
redirect_to [:manage, #room]
else
render 'new'
end
end
def show
#room = Room.find(params[:id])
end
def edit
#room = Room.find(params[:id])
end
def update
#room = Room.find(params[:id])
if #room.update(params[:rooms].permit(:number_of_rooms, :occupancy, :room_type, :gender, :title))
redirect_to [:manage, #room]
else
render 'edit'
end
end
def destroy
#room = Room.find(params[:id])
#room.destroy
redirect_to manage_index_path
end
private
def room_params
params.require(:rooms).permit(:number_of_rooms, :occupancy, :room_type, :gender, :title)
end
end
and under ... manage/rooms/_index.html.erb it is rendered in /layouts/_navigation_left.html.erb
Thanks! If you need more information just ask.
Thanks sorry I´m quite new to Rails. How do I change the controller / routes so I can manage not just #rooms but even #foo, #fee ...? Thanks.
I try to use:
I do like to show <%= #room.title %> <%= #room.number_of_rooms %>or do you need something else? Sorry!
and <%= render 'manage/rooms/index'%>
So I have Votes model, that means a votes for posts. My controller have create action, and it works fine, but when i want to take count, i recive nothing.
See the controller:
class VotesController < ApplicationController
def new
end
def create
#post = Post.find(params[:post_id])
#vote = #post.votes.create(votes_params)
#vote.save
redirect_to #post
end
def index // here is the problem
#post = Post.find(params[:post_id])
#pro = #post.votes.where(stare: false).count
#contra = #post.votes.where(stare: false).count
end
private
def votes_params
params.require(:vote).permit(:stare).merge(user_id: current_user.id)
end
end
Problem is because in index action #post have a nil value... How to repair?
routes.rb:
resources :posts do
resources :votes
collection do
get 'for_vote'
get 'considered'
get 'solved'
end
end