Reputation:
I have this undefined method "name", It used to work though... I don't know what I messed up... I need your help please...
index.html.slim
.container
.row
.col-xs-12
h1.text-gray Tutorials
h4 Search by Title
=form_tag tutos_path, :method => 'get' do
=text_field_tag :search, params[:search]
=submit_tag "Search", class:'btn btn-default'
.col-xs-12
-if user_signed_in?
= link_to "Create a tuto", new_tuto_path, class:"btn btn-success"
#tutos.transitions-enabled
[email protected] do |tuto|
.box.panel-default
-if tuto.category.name == "Ruby"
= link_to(image_tag("select/ruby.png"), tuto_path(tuto))
-elsif tuto.category.name == "Rails 4"
= link_to(image_tag("select/rails4.png"), tuto_path(tuto))
-elsif tuto.category.name == "Rails 5"
= link_to(image_tag("select/rails5.png"), tuto_path(tuto))
-elsif tuto.category.name == "Heroku"
= link_to(image_tag("select/heroku.png"), tuto_path(tuto))
-elsif tuto.category.name == "AWS-Amazon"
= link_to(image_tag("select/aws.png"), tuto_path(tuto))
h3 = link_to tuto.title, tuto_path(tuto), class:"title-link"
h6
| Created by:
span<>
= tuto.user.full_name
br
span.glyphicon.glyphicon-heart
span<>
= tuto.get_upvotes.size
br
br
My categories are created in the console:
Category Load (1.4ms) SELECT "categories".* FROM "categories"
=> #<ActiveRecord::Relation [#<Category id: 1, name: "Ruby", created_at: "2016-09-26 09:03:17", updated_at: "2016-09-26 09:03:17">, #<Category id: 2, name: "Rails 4", created_at: "2016-09-26 09:03:25", updated_at: "2016-09-26 09:03:25">, #<Category id: 3, name: "Rails 5", created_at: "2016-09-26 09:03:30", updated_at: "2016-09-26 09:03:30">, #<Category id: 4, name: "Heroku", created_at: "2016-09-26 09:03:35", updated_at: "2016-09-26 09:03:35">, #<Category id: 5, name: "AWS-Amazon", created_at: "2016-09-26 09:03:43", updated_at: "2016-09-26 09:03:43">]>
2.3.1 :002 >
tutos_controller.rb
class TutosController < ApplicationController
before_action :authenticate_user!, only: [:new, :create]
before_action :set_tuto, only: [:show, :edit, :update, :destroy, :upvote]
def index
@tutos = Tuto.all.includes(:user && :category)
@categories = Category.all
keyword_search
end
def show
@tuto = Tuto.find(params[:id])
@user = User.all
end
def new
@tuto = Tuto.new
end
def edit
end
def create
@tuto = Tuto.new(tuto_params)
@tuto.user_id = current_user.id
respond_to do |format|
if @tuto.save
flash[:success] = "Test"
format.html { redirect_to @tuto, notice: 'Tuto was successfully created.' }
format.json { render :show, status: :created, location: @tuto }
else
format.html { render :new }
format.json { render json: @tuto.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @tuto.update(tuto_params)
format.html { redirect_to @tuto, notice: 'Tuto was successfully updated.' }
format.json { render :show, status: :ok, location: @tuto }
else
format.html { render :edit }
format.json { render json: @tuto.errors, status: :unprocessable_entity }
end
end
end
def destroy
@tuto.destroy
respond_to do |format|
format.html { redirect_to tutos_url, notice: 'Tuto was successfully destroyed.' }
format.json { head :no_content }
end
end
def upvote
@tuto.upvote_by current_user
redirect_to :back
end
def keyword_search
@tutos = Tuto.search(params[:search])
end
private
def set_tuto
@tuto = Tuto.find(params[:id])
end
def tuto_params
params.require(:tuto).permit(:title, :content, :id, :user_id, :category_id)
end
end
The schema
ActiveRecord::Schema.define(version: 20160920133801) do
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "tutos", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "title"
t.text "content"
t.integer "user_id"
t.integer "category_id"
end
add_index "tutos", ["user_id"], name: "index_tutos_on_user_id"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "first_name"
t.string "last_name"
t.boolean "admin"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
create_table "votes", force: :cascade do |t|
t.integer "votable_id"
t.string "votable_type"
t.integer "voter_id"
t.string "voter_type"
t.boolean "vote_flag"
t.string "vote_scope"
t.integer "vote_weight"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"
end
tuto_model.rb
class Tuto < ActiveRecord::Base
acts_as_votable
belongs_to :user
belongs_to :category
validates :category_id, presence: true
def self.search(search)
if search
where(["title LIKE ?","%#{search}%"])
else
all
end
end
end
category_model.rb
class Category < ActiveRecord::Base
has_many :tutos
end
this is the error i have with deepak's suggestion, ( BTW I really like the refactoing he suggested!!)
index.html.slim:29: syntax error, unexpected ';', expecting ')' ...temple_html_pretty1)))).to_s)); ... ^
Extracted source (around line #29):
27
28
29
30
31
32
[email protected] do |tuto|
.box.panel-default
= link_to image_tag(image_by_category(tuto.category.try(:name)), tuto_path(tuto)
h3 = link_to tuto.title, tuto_path(tuto), class:"title-link"
Upvotes: 2
Views: 262
Reputation: 23661
One of the category is nil
that's why you are getting
undefined method "name" for nil:NilClass
Use try
index.html.slim
[email protected] do |tuto|
.box.panel-default
-if tuto.category.try(:name) == "Ruby"
= link_to(image_tag("select/ruby.png"), tuto_path(tuto))
-elsif tuto.category.try(:name) == "Rails 4"
= link_to(image_tag("select/rails4.png"), tuto_path(tuto))
-elsif tuto.category.try(:name) == "Rails 5"
= link_to(image_tag("select/rails5.png"), tuto_path(tuto))
-elsif tuto.category.try(:name) == "Heroku"
= link_to(image_tag("select/heroku.png"), tuto_path(tuto))
-elsif tuto.category.try(:name) == "AWS-Amazon"
= link_to(image_tag("select/aws.png"), tuto_path(tuto))
Also I will suggest to make use of helper method in your code
index.html.slim
[email protected] do |tuto|
.box.panel-default
= link_to image_tag(image_by_category(tuto.category.try(:name))), tuto_path(tuto)
application_helper.rb
def image_by_category(name)
images = {
"Ruby" => "select/ruby.png",
"Rails 4" => "select/rails4.png",
"Rails 5" => "select/rails5.png",
"Heroku" => "select/heroku.png",
"AWS-Amazon" => "select/aws.png"
}
images[name]
end
Upvotes: 2
Reputation: 18647
In this @tutos loop, one of your categories is not present or nil, so name method is not present for nil and throwing you an error, for this, you can solve it in two ways.
1) check if category is present at the starting of the loop, if present, then only go in,
[email protected] do |tuto|
.box.panel-default
-if tuto.category.present?
-if tuto.category.name == "Ruby"
= link_to(image_tag("select/ruby.png"), tuto_path(tuto))
-elsif tuto.category.name == "Rails 4"
= link_to(image_tag("select/rails4.png"), tuto_path(tuto))
-elsif tuto.category.name == "Rails 5"
= link_to(image_tag("select/rails5.png"), tuto_path(tuto))
-elsif tuto.category.name == "Heroku"
= link_to(image_tag("select/heroku.png"), tuto_path(tuto))
-elsif tuto.category.name == "AWS-Amazon"
= link_to(image_tag("select/aws.png"), tuto_path(tuto))
2) Use try
which continues execution without checking the error
[email protected] do |tuto|
.box.panel-default
-if tuto.try(:category).try(:name) == "Ruby"
= link_to(image_tag("select/ruby.png"), tuto_path(tuto))
-elsif tuto.try(:category).try(:name) == "Rails 4"
= link_to(image_tag("select/rails4.png"), tuto_path(tuto))
-elsif tuto.try(:category).try(:name) == "Rails 5"
= link_to(image_tag("select/rails5.png"), tuto_path(tuto))
-elsif tuto.try(:category).try(:name) == "Heroku"
= link_to(image_tag("select/heroku.png"), tuto_path(tuto))
-elsif tuto.try(:category).try(:name) == "AWS-Amazon"
= link_to(image_tag("select/aws.png"), tuto_path(tuto))
Upvotes: 1
Reputation: 230336
Tuto.all.includes(:user && :category)
Should be
Tuto.all.includes(:user, :category)
Upvotes: 1