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'%>
Related
**I made a controller and model for post and not able to show my post's
title on the show page but repeatedly i am getting the same error **
my posts_controller code :
class PostsController < ApplicationController
def index
end
def new
end
def create
#render plain: params[:post][:body].inspect
#post = Post.new(post_params)
if #post.save
redirect_to posts_path
else
render "new"
end
end
def show
#post= Post.find(:id=>params[:id])
# #article = "prateek"
end
private
def post_params
params.require(:post).permit(:title,:body)
end
end
my show.html.erb file :
<h1><%= #post.title %></h1>
my post.rb file:
class Post < ApplicationRecord
end
**I expect the result but I didn't get anything right
error = NoMethodError in Posts#show
undefined method `title' for nil:NilClass**
You're passing an hash to find, while you're suppose to pass just the id.
#post= Post.find(params[:id])
or use find_by if you want to pass an hash
#post= Post.find_by(:id => params[:id])
I have an app where users can ask questions and bookmark certain questions. I'm done with the users, questions, and answers, so I've added a BookmarkController & Bookmarks model. At first, I considered using associations, but my app has a few associations already so I'm (or I've attempted at) using query parameters such as user_id and question_id to fetch bookmarks.
The structure is a bit like StackOverflow. A user navigates to a single question view and bookmarks it on that page. This creates a new bookmark model containing the user_id of current_user and the question_id. The user can go to his profile to view all the questions he bookmarked, fetched using his user_id. (Answers cannot be bookmarked. Only questions.)
I've been getting a 'param is missing or the value is empty: bookmark' error, although I have followed similar steps I did for my QuestionsController. It would be great if someone could help me out in identifying what's wrong/bad about my code!
rake routes (first part omitted)
bookmark_question PUT /questions/:id/bookmark(.:format) questions#bookmark
questions GET /questions(.:format) questions#index
POST /questions(.:format) questions#create
new_question GET /questions/new(.:format) questions#new
edit_question GET /questions/:id/edit(.:format) questions#edit
question GET /questions/:id(.:format) questions#show
PATCH /questions/:id(.:format) questions#update
PUT /questions/:id(.:format) questions#update
DELETE /questions/:id(.:format) questions#destroy
route.rb (excerpt)
# Questions
get '/questions/:id' => 'bookmarks#create'
show.html.erb (questions#show)
<% if current_user %>
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create' %>
<% end %>
BookmarksController
class BookmarksController < ApplicationController
def new
#bookmark = Bookmark.new
end
def create
#question = Question.find(params[:id]) # when I delete this line, I get a new error - "undefined local variable 'params'"
#bookmark = Bookmark.new(bookmark_params)
#bookmark.user_id = current_user.id
#bookmark.question_id = #question.id
#bookmark.save
redirect_to #question
end
def destroy
end
private
def bookmark_params
params.require(:bookmark).permit(:user_id, :question_id)
end
end
Bookmark model
class Bookmark < ApplicationRecord
validates :user_id, presence: true
validates :question_id, presence: true
end
QuestionsController
(at the moment, contains no reference to Bookmarks. I thought so because I did the routing, but this might be where I'm going wrong)
class QuestionsController < ApplicationController
def index
#questions = Question.all
end
def show
#question = Question.find(params[:id])
#answers = Answer.all
# Delete only appears when no answers
#deletable = (current_user== User.find(#question.user_id)) && (#question.answers.all.size==0)
end
def new
#question = Question.new
end
def create
if logged_in?
#question = Question.new(question_params)
#question.user_id = current_user.id
#question.save
redirect_to #question
else
redirect_to login_path
end
end
def destroy
#question = Question.find(params[:id])
#question.destroy
redirect_to root_path
end
private
def question_params
params.require(:question).permit(:picture_url, :country, :educational_level, :topic)
end
end
profile index.html.erb (just for ref)
<% if (#bookmarks.count == 0) %>
///
<% else %>
<%= #bookmarks.each do |bookmark| %>
<!-- Show bookmark content here like Question.find(bookmark.question_id) etc -->
<% end %>
<% end %>
I have looked a the previous qns that have the same error as me. But they were all using associations. I hope to not use associations as the bookmark model only needs to keep a record of the user id and qn id.
UPDATE
So, referring to the answers given, I updated my erb to:
<% if logged_in? %>
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create', bookmark: {user_id: current_user.id, question_id: #question.id} %>
<% end %>
hence specifying the controller and action (and the params) that need to be directed. But rails sends an error:
No route matches {:action=>"create", :bookmark=>{:user_id=>2, :question_id=>4}, :controller=>"bookmarks", :id=>"4"}
So I assume it was a routing problem. As Pavan suggested, I did consider nesting my resources, but the nesting is already one level deep, as such:
resources :questions do
resources :answers
end
And I reckon doing something like:
resources :questions do
resources :bookmarks # or resources :bookmarks, only: create
resources :answers
end
won't work. (And it didn't :( )
I'm not so sure how to get this routing problem fixed (tried Googling). Thanks.
param is missing or the value is empty: bookmark
The reason for the error is bookmark_params expects a :bookmark key to be present in the params hash, which in your case is missing since you are not passing any.
Change link_to like below:
<% if current_user %>
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create', bookmark: {user_id: current_user.id, question_id: #question.id} %>
<% end %>
Also, the route get '/questions/:id' => 'bookmarks#create' isn't right and would conflict with this route question GET /questions/:id(.:format) questions#show. I would instead recommend building nested routes
resources :users do
resources :questions do
resources :bookmarks, only: [:create]
end
end
Update:
Along with the above, you should change #question = Question.find(params[:id]) to #question = Question.find(params[:bookmark][:question_id])
'param is missing or the value is empty: bookmark, this error means that, there is no bookmark key present in your params object, but you defined your bookmark_params to have one:
def bookmark_params
params.require(:bookmark).permit(:user_id, :question_id)
end
That's why it's throwing the above error message.
You should make sure you send the user_id and question_id key/value pairs under the bookmark key. Something like this:
bookmark: { user_id: 1, question_id: 2}.
So, your code should look something like this (adding the bookmark to params):
<%= link_to "Bookmark", :controller => 'bookmarks', :action => 'create', bookmark: {user_id: current_user.id, question_id: #question.id} %>
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'm using nested routes,I have :booking table and :hotel table
In my routes.rb
resources :hotels do
resources :bookings
end
In my hotel show.html. erb
<%= link_to 'Book Now', new_booking_path(:hotel_id => #hotel.id) %>
In my bookings_controller.rb
def new
#booking = #hotel.bookings.build
end
When the link is clicked, it generates a link
localhost:3000/bookings/new?hotel_id=4
But I still get an error
NoMethodError
Undefined method 'bookings' for nil:NilClass
Extracted source from
def new
#booking = #hotel.bookings.build
end
It appears that you're not retrieving a Hotel object in your new method for your controller. So when you call bookings on the #hotel variable, the nil exception is thrown. It should look something like:
bookings_controller.rb:
def new
#hotel = Hotel.find(params[:hotel_id])
#booking = #hotel.bookings.build
end
Hope it helps!
I think you made a mistake to find #hotel here, Please do this -
In bookings_controller.rb -
def new
#hotel = Hotel.find(params[:hotel_id])
if #hotel.present?
#booking = #hotel.bookings.build
render :new
else
redirect_to root_path
end
end
I'm getting a NoMethodError in the new action of my business_controller.
It seems to be acessing the #business object for a form in my view and the error occurs then:
undefined method `businesses_path' for
Here is my new method:
def new
if Business.where(:user_id => current_user.id).first.blank?
#business = Business.new
else
redirect_to user_businesses_path(current_user.id)
end
end
My routes are:
resources :users do
resources :businesses
member do
get 'account'
post 'payment'
put 'update_password'
get 'membership'
end
end
mind.blank's suggested changes
before_filter :check_if_user_has_business, :only => :index
def new
#business = Business.new
end
private
def check_if_user_has_business
redirect_to new_user_business_path(current_user) unless current_user.business
end
Do you have a route businesses_path or only user_businesses_path? If you only have the second one then you should specify that URL in your form:
<%= form_for #business, url: user_businesses_path do |f| %>
Also, if you have the correct associations set up, then you can write your if statement as follows:
if current_user.business.nil? # since it's a has_one association
Here's how I would write it:
Class BusinessesController < ApplicationController
before_filter :check_if_user_has_business, only: :new
def new
#business = Business.new
end
private
def check_if_user_has_business
redirect_to user_businesses_path(current_user) if current_user.business
end
end