I am getting NoMethodError in SitesController#index undefined method `name' for nil:NilClass in my Salesman index view and cannot find the culprit.
I have a simple rails app with the following tables: Customer, Salesman and Invoice.
In the index view for the customer table I have the following call:
<% #customers.each do |customer| %>
<%= customer.name %></td>
<%= customer.address %>
<%= customer.salesman.name %>
<% end %>
This is the call that results in the undefined method ´name´ listed above. I made sure the salesman table has a salesman_id foreign key in the customer table. Also, I made the respective association in the models:
class Customer < ActiveRecord::Base
belongs_to :salesman
has_many :invoices
end
class Salesman < ActiveRecord::Base
has_many :customers
end
I tested the customer.salesman.name call in the console and it works flawlessly. The show view for the customer has an exact call like this one and it also works. The only way I can make the customer index pass is by replacing customer.salesman.name to customer.salesman_id returning only the id.
Thank you for your time here.
***schema.rb***
ActiveRecord::Schema.define(version: 20150325172212) do
create_table "customers", force: :cascade do |t|
t.string "name"
t.string "address"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "salesman_id"
end
create_table "invoices", force: :cascade do |t|
t.datetime "date"
t.string "fid"
t.integer "salesman_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "address"
end
create_table "salesmen", force: :cascade do |t|
t.datetime "name"
t.string "address""
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
***controllers***
**customer**
Class CustomersController < ApplicationController
before_action :set_customer, only: [:show, :edit, :update, :destroy]
# GET /customers
# GET /customers.json
def index
#customers = Customer.all
end
# GET /customers/1
# GET /customers/1.json
def show
end
# GET /customers/new
def new
#customer = Customer.new
end
# GET /customers/1/edit
def edit
end
# POST /customers
# POST /customers.json
def create
#customer = Customer.new(customer_params)
respond_to do |format|
if #customer.save
format.html { redirect_to #customer, notice: 'Customer was successfully created.' }
format.json { render :show, status: :created, location: #customer }
else
format.html { render :new }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /customers/1
# PATCH/PUT /customers/1.json
def update
respond_to do |format|
if #customer.update(customer_params)
format.html { redirect_to #customer, notice: 'Customer was successfully updated.' }
format.json { render :show, status: :ok, location: #customer }
else
format.html { render :edit }
format.json { render json: #customer.errors, status: :unprocessable_entity }
end
end
end
# DELETE /customers/1
# DELETE /customers/1.json
def destroy
#customer.destroy
respond_to do |format|
format.html { redirect_to customers_url, notice: 'Customer was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_cliente
#cliente = Cliente.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def customer_params
params.require(:customer).permit(:name, :address, :salesman_id)
end
end
***salesman***
class SalesmenController < ApplicationController
before_action :set_salesman, only: [:show, :edit, :update, :destroy]
# GET /salesmans
# GET /salesmans.json
def index
#salesmen = Salesman.all
end
# GET /salesmans/1
# GET /salesmans/1.json
def show
end
# GET /salesmans/new
def new
#salesman = Salesman.new
end
# GET /salesmans/1/edit
def edit
end
# POST /salesmans
# POST /salesmans.json
def create
#salesman = Salesman.new(salesman_params)
respond_to do |format|
if #salesman.save
format.html { redirect_to #salesman, notice: 'Salesman was successfully created.' }
format.json { render :show, status: :created, location: #salesman }
else
format.html { render :new }
format.json { render json: #salesman.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /salesmans/1
# PATCH/PUT /salesmans/1.json
def update
respond_to do |format|
if #salesman.update(salesman_params)
format.html { redirect_to #salesman, notice: 'Salesman was successfully updated.' }
format.json { render :show, status: :ok, location: #salesman }
else
format.html { render :edit }
format.json { render json: #salesman.errors, status: :unprocessable_entity }
end
end
end
# DELETE /salesmans/1
# DELETE /salesmans/1.json
def destroy
#salesman.destroy
respond_to do |format|
format.html { redirect_to salesmans_url, notice: 'Salesman was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_salesman
#salesman = Salesman.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def salesman_params
params.require(:salesman).permit(:name, :address)
end
**invoice**
class InvoicesController < ApplicationController
before_action :set_invoice, only: [:show, :edit, :update, :destroy]
# GET /invoices
# GET /invoices.json
def index
#invoices = Invoice.all
end
# GET /invoices/1
# GET /invoices/1.json
def show
#invoice = Invoice.find(params[:id])
#ordenes = #invoice.ordenes
end
# GET /invoices/new
def new
#invoice = Invoice.new
end
# GET /invoices/1/edit
def edit
end
# POST /invoices
# POST /invoices.json
def create
#invoice = Invoice.new(invoice_params)
respond_to do |format|
if #invoice.save
format.html { redirect_to #invoice, notice: 'Invoice was successfully created.' }
format.json { render :show, status: :created, location: #invoice }
else
format.html { render :new }
format.json { render json: #invoice.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /invoices/1
# PATCH/PUT /invoices/1.json
def update
respond_to do |format|
if #invoice.update(invoice_params)
format.html { redirect_to #invoice, notice: 'Invoice was successfully updated.' }
format.json { render :show, status: :ok, location: #invoice }
else
format.html { render :edit }
format.json { render json: #invoice.errors, status: :unprocessable_entity }
end
end
end
# DELETE /invoices/1
# DELETE /invoices/1.json
def destroy
#invoice.destroy
respond_to do |format|
format.html { redirect_to invoices_url, notice: 'Invoice was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_invoice
#invoice = Invoice.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def invoice_params
params.require(:invoice).permit(:date, :fid, :name, :address, :salesman_id)
end
end
-davefogo
Add the following to your views instead of what you currently have<%= customer.salesman.name if customer.salesman %>
This will ensure that you're not calling name when customer doesn't have a salesman.
Try this:
<% #customers.each do |customer| %>
<%= customer.name %>
<%= customer.address %>
<%= customer.salesman.try(:name) %>
<% end %>
Do this:
<% #customers.each do |customer| %>
<% Rails.logger.debug "\n\n#{#customers} has a nil customer in it\n\n" if customer.nil? %>
<% Rails.logger.debug "\n\nCustomer #{customer.id} has no salesman for [#{customer.salesman_id}]\n\n" if customer.salesman.nil? %>
<%= customer.name %>
<%= customer.address %>
<%= customer.salesman.name %>
<% end %>
...and then check your logs after hitting the index.
Related
getting this error message in my terminal when trying to seed csv data:
rake aborted!
ActiveRecord::AssociationTypeMismatch: Year(#70340979867760) expected, got 1967 which is an instance of Integer(#70340969823320)
here is my rake file code:
require 'csv'
namespace :albums do
desc "pull albums data into database"
task seed_albums: :environment do
#drop the old table data before importing the new stuff
Albums.destroy_all
CSV.foreach("lib/assets/Albums.csv", :headers =>true) do |row |
puts row.inspect #just so that we know the file's being read
#create new model instances with the data
Albums.create!(
name: row[0],
year: row[1].to_i)
end
end
end
here is my scheme code:
create_table "albums", force: :cascade do |t|
t.string "name"
t.integer "year"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
and here is my controller code:
class AlbumsController < ApplicationController
before_action :set_albums, only: [:show, :edit, :update, :destroy]
# GET /albums
# GET /albums.json
def index
#albums = Albums.all
end
# GET /albums/1
# GET /albums/1.json
def show
end
# GET /albums/new
def new
#albums = Albums.new (params[:album])
end
# GET /albums/1/edit
def edit
end
# POST /albums
# POST /albums.json
def create
#albums = Albums.new
respond_to do |format|
if #albums.save
format.html { redirect_to #albums, notice: 'albums was successfully created.' }
format.json { render :show, status: :created, location: #albums }
else
format.html { render :new }
format.json { render json: #albums.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /albums/1
# PATCH/PUT /albums/1.json
def update
respond_to do |format|
if #albums.update(albums_params)
format.html { redirect_to #albums, notice: 'albums was successfully updated.' }
format.json { render :show, status: :ok, location: #albums }
else
format.html { render :edit }
format.json { render json: #albums.errors, status: :unprocessable_entity }
end
end
end
# DELETE /albums/1
# DELETE /albums/1.json
def destroy
#albums.destroy
respond_to do |format|
format.html { redirect_to albums_url, notice: 'albums was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_albums
#albums = albums.find(params[:id])
end
# Only allow a list of trusted parameters through.
def albums_params
params.require(:albums).permit(:name, :term)
end
end
Thanks in advance
So I have locker model which is just a basic scaffold
def change
create_table :lockers do |t|
t.references :user
t.integer :lockerNo
t.string :wing
t.string :sttatus
t.string :comment
t.timestamps
end
end
end
and also a user model which is just basic devise.
I want users to be able to select a locker they want,
So I want to list all the lockers and then users click on Select button and then the locker gets assigned to the user i.e the locker_id updates to the current user
This is my controller
before_action :set_locker, only: [:show, :edit, :update, :destroy]
# GET /lockers
# GET /lockers.json
def index
#lockers = Locker.all
end
# POST /lockers
# POST /lockers.json
def create
#locker = Locker.new(locker_params)
respond_to do |format|
if #locker.save
format.html { redirect_to #locker, notice: 'Locker was successfully created.' }
format.json { render :show, status: :created, location: #locker }
else
format.html { render :new }
format.json { render json: #locker.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /lockers/1
# PATCH/PUT /lockers/1.json
def update
respond_to do |format|
if #locker.update(locker_params)
format.html { redirect_to #locker, notice: 'Locker was successfully updated.' }
format.json { render :show, status: :ok, location: #locker }
else
format.html { render :edit }
format.json { render json: #locker.errors, status: :unprocessable_entity }
end
end
end
def assign_locker
if #locker.sttatus = Available
#locker = Locker.find(params[:id])
#locker.user_id = current_user.id
#locker.save
end
redirect_to root_path
end
private
def set_locker
#locker = Locker.find(params[:id])
end
def locker_params
params.require(:locker).permit(:user_id, :lockerNo, :wing, :sttatus, :comment)
end
end
Make a controller method for updating the locker with the current user.
Put /lockers/[locker_id]
def update
locker = Locker.findById(params[:locker_id])
locker.user = current_user
if locker.save
head 200
else
head 422
end
end
That's really ugly code that makes a few assumptions... but is it not what you're trying to do?
I am having trouble uploading audio with the carrierwave gem, when i post the the audio file all that displays is the audio url link. First time using the gem and not sure if i am using carrierwave correctly. Just trying to display the audio file on the show page.
class AudioUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
storage :file
include CarrierWave::Audio
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= #music.title %>
<%= #music.audio.url() %>
</p>
<%= link_to 'Edit', edit_music_path(#music) %> |
<%= link_to 'Back', musics_path %>
music.rb
class Music < ApplicationRecord
mount_uploader :audio, AudioUploader
end
schema
ActiveRecord::Schema.define(version: 20170606155943) do
create_table "musics", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "audio"
end
end
music controller
class MusicsController < ApplicationController
before_action :set_music, only: [:show, :edit, :update, :destroy]
# GET /musics
# GET /musics.json
def index
#musics = Music.all
end
# GET /musics/1
# GET /musics/1.json
def show
end
# GET /musics/new
def new
#music = Music.new
end
# GET /musics/1/edit
def edit
end
# POST /musics
# POST /musics.json
def create
#music = Music.new(music_params)
respond_to do |format|
if #music.save
format.html { redirect_to #music, notice: 'Music was successfully created.' }
format.json { render :show, status: :created, location: #music }
else
format.html { render :new }
format.json { render json: #music.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /musics/1
# PATCH/PUT /musics/1.json
def update
respond_to do |format|
if #music.update(music_params)
format.html { redirect_to #music, notice: 'Music was successfully updated.' }
format.json { render :show, status: :ok, location: #music }
else
format.html { render :edit }
format.json { render json: #music.errors, status: :unprocessable_entity }
end
end
end
# DELETE /musics/1
# DELETE /musics/1.json
def destroy
#music.destroy
respond_to do |format|
format.html { redirect_to musics_url, notice: 'Music was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_music
#music = Music.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def music_params
params.require(:music).permit(:title, :audio)
end
end
Running Rails:
Rails 4.2.5
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
I'm trying to return a value from one model (eds) within a view of another model (clients).
I believe I I'm very close to a solution. However, I'm at a road block. I'm want return the name of the school (eds) in the client view.
As of now, I'm defining this in my client controller:
def index
#eds_school = Ed.name
end
I thought that Ed.name should work but it doesn't.
Then I'm calling the statement in the view:
<tb><%= #eds_school %></td>
I think my issue is within the client controller.
Here is the db schema:
create_table "eds", force: :cascade do |t|
t.string "name"
t.string "grade"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "school"
t.text "JtText"
end
Eds Controller:
class EdsController < ApplicationController
before_action :set_ed, only: [:show, :edit, :update, :destroy]
# GET /eds
# GET /eds.json
def index
#eds = Ed.all
end
# GET /eds/1
# GET /eds/1.json
def show
end
# GET /eds/new
def new
#ed = Ed.new
end
# GET /eds/1/edit
def edit
end
# POST /eds
# POST /eds.json
def create
#ed = Ed.new(ed_params)
respond_to do |format|
if #ed.save
format.html { redirect_to #ed, notice: 'Ed was successfully created.' }
format.json { render :show, status: :created, location: #ed }
else
format.html { render :new }
format.json { render json: #ed.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /eds/1
# PATCH/PUT /eds/1.json
def update
respond_to do |format|
if #ed.update(ed_params)
format.html { redirect_to #ed, notice: 'Ed was successfully updated.' }
format.json { render :show, status: :ok, location: #ed }
else
format.html { render :edit }
format.json { render json: #ed.errors, status: :unprocessable_entity }
end
end
end
# DELETE /eds/1
# DELETE /eds/1.json
def destroy
#ed.destroy
respond_to do |format|
format.html { redirect_to eds_url, notice: 'Ed was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ed
#ed = Ed.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def ed_params
params.require(:ed).permit(:name)
end
end
Client Controller:
class ClientsController < ApplicationController
before_action :authenticate_user!
before_action :set_client, only: [:show, :edit, :update, :destroy]
# GET /clients
# GET /clients.json
def index
#clients = Client.all.uniq.order("created_at DESC")
#clients_count = Client.uniq.count
#eds_school = Ed.name
end
# GET /clients/1
# GET /clients/1.json
def show
##notes = Note.all.uniq.order("created_at DESC")
#notes = Note.where(client_id: #client.id) #Where a note belong to the current user
end
# GET /clients/new
def new
#client = Client.new
end
# GET /clients/1/edit
def edit
end
# POST /clients
# POST /clients.json
def create
#client = Client.new(client_params)
respond_to do |format|
if #client.save
format.html { redirect_to #client, notice: 'Client was successfully created.' }
format.json { render :show, status: :created, location: #client }
else
format.html { render :new }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
#if params[:remove_image]
##client.remove_image!
#client.save
#end
respond_to do |format|
if #client.update(client_params)
format.html { redirect_to #client, notice: 'Client was successfully updated.' }
format.json { render :show, status: :ok, location: #client }
else
format.html { render :edit }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
end
# DELETE /clients/1
# DELETE /clients/1.json
def destroy
#client.destroy
respond_to do |format|
format.html { redirect_to clients_url, notice: 'Client was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_client
#client = Client.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def client_params
params.require(:client).permit(:firstName, :lastName,:dob, :name, :gender_id, :RefbText, :JtText, :text_rs, :msub, :text_id, :ged_id, :mj_id, :od_id, :otc_id, :cigarette_id, :alcohol_id, :grad, :remove_image, :rh_options, :insurance_id, :state_id, :ed_id, :wk_id, :grade_id, :rsource_id, :image, :race_id, :employment_id, :comments, :clientemail, :phone, :truma_id, :college_id, :enrolled, :address, :city, :state, :zipcode, rhealth_ids:[], mhealth_ids:[], cparent_ids:[], preg_ids:[], referral_ids:[], refa_ids:[], refb_ids:[])
#params.require(:client).permit(:name, mhealth_ids:[])
end
end
Code Sample of Client Model:
class Client < ActiveRecord::Base
belongs_to :ed
end
Code Sample of Client DB Schema:
create_table "clients", force: :cascade do |t|
t.integer "ed_id"
end
Ed Controller:
class Ed < ActiveRecord::Base
has_many :clients
end
Its not completely clear what you're trying to achieve. Your code isnt working bcause name is an attribute and therefore a method on an instance of the class Eds. Look up the difference between class methods and instance methods. You need to find a particular instance of Eds and then call the name method on it e.g.
eds_school = Eds.find(1).name
where 1 is the database record in the eds table with an id of 1.
Because a client belongs to an Eds, you can access the eds name through a client instance. To display the eds.name for each client, you will need to loop through the clients variable. In the view
<% #clients.each do |client| %>
<%= client.eds.name %>
<% end %>
I know this is a very common issue, but I can't resolve this with any of the other topics.
this is the issue:
undefined local variable or method `stop' for #<#:0xb16e8c6c>
app/views/stops/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>City name:</strong>
<%= #stop.city %>
</p>
<p>
<strong>Arrival time:</strong>
<%= #stop.Arrival_time %>
</p>
<p>
<strong>Route:</strong>
<%= #stop.Route_id %>
</p>
<%= link_to 'Edit', edit_stop_path(#stop) %> |
<%= link_to 'Back', stops_path %>
db/schema.rb
create_table "stops", force: :cascade do |t|
t.time "Arrival_time"
t.integer "Route_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "city"
end
app/controllers/stops_controller
class StopsController < ApplicationController
before_action :set_stop, only: [:show, :edit, :update, :destroy]
# GET /stops
# GET /stops.json
def index
#stops = Stop.all
end
# GET /stops/1
# GET /stops/1.json
def show
end
# GET /stops/new
def new
#stop = Stop.new
end
# GET /stops/1/edit
def edit
end
# POST /stops
# POST /stops.json
def create
#stop = Stop.new(stop_params)
respond_to do |format|
if #stop.save
format.html { redirect_to #stop, notice: 'Stop was successfully created.' }
format.json { render :show, status: :created, location: #stop }
else
format.html { render :new }
format.json { render json: #stop.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /stops/1
# PATCH/PUT /stops/1.json
def update
respond_to do |format|
if #stop.update(stop_params)
format.html { redirect_to #stop, notice: 'Stop was successfully updated.' }
format.json { render :show, status: :ok, location: #stop }
else
format.html { render :edit }
format.json { render json: #stop.errors, status: :unprocessable_entity }
end
end
end
# DELETE /stops/1
# DELETE /stops/1.json
def destroy
#stop.destroy
respond_to do |format|
format.html { redirect_to stops_url, notice: 'Stop was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_stop
#stop = Stop.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def stop_params
params.require(:stop).permit(:city, :Arrival_time, :Route_id)
end
end
I don't see where the problem is.. can you help me? thank you
You're getting this error because #stop isn't defined on the show page. You fix this by defining it in the show method in your Stop Controller.
I'm assuming the show page will pass a parameter for the shop id. If so you can define it like this:
def show
#stop = Stop.find(params[:id])
end