How to pass a Rails variable into a route - ruby-on-rails

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

Related

the foreign key is just passing to the new form not the create action (ruby on rails)

This is my controllers and routes
I have a albums controller and a bands controler with their models, and I want to access the foreign key to pass it, but it told me bands is blank
def show
#album = Album.find_by(:id => params[:id])
render :show
end
def new
#band = Band.find_by(:id => params[:band_id])
#albums = Album.new(:band_id => params[:band_id])
render :new
end
def create
#albums = Album.new(albums_params)
if #albums.save
flash[:success] = "Album created successfully"
redirect_to album_path(#albums.id)
else
#band = #albums.band
flash[:error] = #albums.errors.full_messages
render :new
end
end
def update
render :edit
end
def edit
end
def destroy
end
private
def albums_params
params.require(:albums).permit(:name, :band_id, :live, :year)
end
end```
resources :bands do
resources :albums, :only => :new
end
Try to pass Band relation like below.
def new
#band = Band.find_by(:id => params[:band_id])
#albums = Album.new(:band => #band)
render :new
end
OR check your code. Can you find Band with correct id?
#band = Band.find_by(:id => params[:band_id])
AND check your Views
You must put someting like below
<%=form.hidden_field :band_id, value: #albums.band_id%>
OR
<%=form.hidden_field :band_id, value: #band.id %>

why does my routes give me wrong direction

I'm having a association between user, store and item like this:
user has one store
store has many items
item belongs to store
So when I create item it must belongs to the current user's store
Now, I logged in as user_1 , I want to search for user_2's item. But if I didn't create user_1's store, It keep redirecting me to localhost:3000/stores
in items_controller.rb:
class ItemsController < ApplicationController
before_action :find_item, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, only: [:new, :edit]
def index
if params[:category].blank?
#items = Item.all.order("created_at DESC")
end
if params[:category]
#category_id = Category.find_by(name: params[:category]).id
#items = Item.where(category_id: #category_id).order("created_at DESC")
end
end
def show
end
def new
#store = current_user.store
#item = #store.items.build
#categories = Category.all.map{ |c| [c.name, c.id] }
end
def update
#item.category_id = params[:category_id]
if #item.update(item_params)
redirect_to item_path(#item)
else
render 'edit'
end
end
def create
#store = current_user.store
#item = #store.items.build(item_params)
#item.category_id = params[:category_id]
if #item.save
flash[:success] = "Creating item success"
redirect_to #item
else
render 'new'
end
end
private
def item_params
params.require(:item).permit(:code, :name, :description, :producer, :item_img, :store_id,
:category_id )
end
def find_item
#item = Item.find(params[:id])
end
def find_user
#user = User.find_by(params[:user_id])
end
end
in stores_controller.rb:
class StoresController < ApplicationController
before_action :find_store, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :find_user
def show
if current_user.store.blank?
redirect_to new
else
#items = Item.where(store_id: #store.id)
end
end
def index
#stores = Store.all.order("created at DESC")
end
def new
#store = current_user.build_store
end
def create
#store = current_user.build_store(store_params)
if #store.save
session[:store_id] = #store.id
flash[:success] = "Creating item success"
redirect_to #store, notice: 'success'
else
render 'new'
end
end
private
def store_params
params.require(:store).permit( :name , :user_id)
end
def find_store
#store = Store.find(params[:id])
end
def find_user
#user = Store.find_by(params[:user_id])
end
end
The error raised whenever I click on the button in items/show.html.erb.
In items/show.html.erb:
<button>see more item from:<%= link_to #item.store.name, store_path(#item.store.id)%></button>
in routes.rb:
devise_for :users
resources :items
resources :stores
In the show method for stores_controller, I still want to load the current_user's store in navbar section to make sure he can add more items to his store when he logged in.
I'm still a newbie in rails and I'm looking for solutions to solve this problem :-)
If a store requires a user_id then you don't need before_action :find_user because you can get the store's user just by calling store.user
It looks like you require the current_user to have a store but what if they are not logged in? Shouldn't it be this?
def show
if current_user && current_user.store.blank?
redirect_to new
else
#items = Item.where(store_id: #store.id)
end
end

How to access a variable from a different controller to make a custom download action work

I have a resumes controller and a welcomes controller in my app. The welcomes controller has only an index action which is there for the root page. The purpose of the resumes controller is to upload(new/create), download(download) etc. pdf files as an logged in user and it works great so far.
I want to implement the resume download feature on the rootpage as well.(welcomes_controller /index).
How can I accomplish this?
Since I can not call the variable to access the resume model from the welcomes controller. How should the routes be? What should I modify on the welcomes_controller?
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'welcomes#index'
resources :resumes do
get :download, on: :member
end
get '*path' => redirect('/')
end
resumes_controller.rb
class ResumesController < ApplicationController
around_filter :catch_not_found
before_action :find_resume, only: [ :show, :edit, :update, :destroy, :download ]
before_action :authenticate_user!
def show
end
def new
if #resume = current_user.resume
redirect_to #resume
else
#resume = Resume.new
end
end
def create
#resume = current_user.build_resume(resume_params)
if #resume.save
redirect_to #resume
else
render :new
end
end
def edit
end
def update
if #resume.update resume_params
redirect_to #resume, notice: "Your resume was successfully saved!"
else
render 'edit'
end
end
def destroy
#resume.destroy
redirect_to new_resume_path, notice: "Your resume was successfully deleted!"
end
def download
send_data #resume, type: "application/pdf", disposition: "attachment"
end
private
def resume_params
params.require(:resume).permit( :user_id, :download_file, :remove_download_file)
end
def find_resume
#resume = Resume.find(params[:id])
end
def catch_not_found
yield
rescue ActiveRecord::RecordNotFound
redirect_to(root_url, :notice => 'Record not found')
end
end
resumes/show.html.erb
...
...
<%= link_to "Download", download_resume_path(#resume), "data-turbolinks" => false %>
welcomes_controller.rb
class WelcomesController < ApplicationController
def index
end
end
you can access Resume model from welcome controller, although controller is welcome you can call Resume model see sample below
class WelcomesController < ApplicationController
def index
# you can call Resume model frome here
#resumes = Resume.all
end
def show
#resume = Resume.find(params[:id])
end
end

Couldn't find User with 'id'=1003

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.

Rails: param is missing or the value is empty. strong parameters in controller

i have this controller
class StoresController < ApplicationController
before_filter :authenticate_business!, :except => [:index, :show]
def index
##stores = Store.paginate(:page => params[:page])#, :per_page => 8)
if params[:query].present?
#stores = Store.search(params[:query], page: params[:page])
else
#stores = Store.all.page params[:page]
end
end
def show
#store = Store.friendly.find(params[:id])
if request.path != store_path(#store)
redirect_to #store, status: :moved_permanently
end
end
def new
#store = Store.new
end
def create
#store = Store.new(store_params)
#store.business_id = current_business.id
if #store.save
redirect_to #store
else
render 'new'
end
end
def edit
#store = Store.friendly.find(params[:id])
end
def update
#store = Store.friendly.find(params[:id])
if #store.update(store_params)
redirect_to #store
else
render 'edit'
end
end
def destroy
#store = Store.friendly.find(params[:id])
#store.destroy
redirect_to stores_url
end
private
def store_params
params.require(:store).permit(:name, :description, :address, :telephone, :email, :website)
end
end
and a view with a form to create a new store.
<%= form_for #store do |f| %>
.......
code
......
<% end %>
The problem is that when i submit the form, it gives me this error "param is missing or the value is empty: store", pointing at line "params.require(:store).permit(:name, :description, :address, :telephone, :email, :website)"
Any idea to solve this problem?
Thank you.
I had this same issue and it was caused by a route issue, as discussed in the comments, causing the form not to post any data.
I think what you need is to make sure 'get' requests to the 'new' route access your 'new' method, while 'post' requests to the 'new' route access your 'create' method. Something like:
get 'stores/new' => 'stores#new'
post 'stores/new' => 'stores#create'

Resources