rails - 如果查看条件 - 未定义方法`id'为零:NilClass

时间:2016-09-13 21:51:16

标签: ruby-on-rails

我有一个名为@Subdomain的课程:

这是我的控制器:



class SubdomainsController < ApplicationController
  before_action :authenticate_user!, only: [:edit, :update]
  before_action :set_subdomain, only: [:show, :edit, :update, :destroy]
  before_action :redirect_to_subdomain, only: :show
  before_action :redirect_to_subdomain_show, only: :root, unless: '@subdomain.nil?'

  def root
    render nothing: true
  end

  def index
    @subdomains = Subdomain.all
  end

  def show
  end

  def new
    @subdomain = Subdomain.new
  end

  def edit
  end

  def create
    @subdomain = Subdomain.new(subdomain_params)

    respond_to do |format|
      if @subdomain.save
        format.html { redirect_to @subdomain, notice: 'Subdomain was successfully created.' }
        format.json { render :show, status: :created, location: @subdomain }
      else
        format.html { render :new }
        format.json { render json: @subdomain.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @subdomain.update(subdomain_params)
        format.html { redirect_to @subdomain, notice: 'Subdomain was successfully updated.' }
        format.json { render :show, status: :ok, location: @subdomain }
      else
        format.html { render :edit }
        format.json { render json: @subdomain.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @subdomain.destroy
    respond_to do |format|
      format.html { redirect_to subdomains_url, notice: 'Subdomain was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private

  def redirect_to_subdomain_show
    redirect_to subdomain_url(@subdomain) if @request_subdomain.eql? @subdomain.address
  end

  # Redirect to subdomain... if the current one isn't equal to @subdomain.address column
  def redirect_to_subdomain
    redirect_to subdomain_url(@subdomain, subdomain: @subdomain.address) unless @request_subdomain.eql? @subdomain.address
  end

  def set_subdomain
    @subdomain = Subdomain.find(params[:id])
  end

  def subdomain_params
    @subdomain.assign_attributes(tag_speciality: params[:subdomain][:tag_speciality].split(','))
    params.require(:subdomain).permit(
      :domain_id,
      :address,
      :title,
      :description,
      :is_published,
      :button_text_client,
      :button_text_service,
      :cover,
      :primary_colour,
      :secundary_colour,
      :contrast_colour,
      :logo,
      :find_clients,
      :find_professional,
      :start_relation,
      :publications_wall,
      :tag_speciality,
      :cards_wall
    )
  end
end
&#13;
&#13;
&#13;

在视图中我创建了一个条件:

&#13;
&#13;
     <% if (!@subdomain.id.blank?) %>
         <li>
            <%= link_to cards_from_subdomain_path(subdomain_id: @subdomain.id) do %>
               <i class="fa fa-search fa-lg"></i>
               <span class="hidden-medium"> 
                 &nbsp <%= @subdomain.cards_wall %>
                </span>
            <% end %>
         </li>
         <li>
            <%= link_to publications_from_subdomain_path(subdomain_id: @subdomain.id) do %>
                 <i class="icon-grid fa-lg"></i> 
                 <span class="hidden-medium"> 
                   &nbsp <%= @subdomain.publications_wall %>
                 </span>
            <% end %>
         </li>
         <% else %>
         <li>Some thing</li>
     <% end %>
&#13;
&#13;
&#13;

以下是模型:

&#13;
&#13;
class Subdomain < ActiveRecord::Base
  belongs_to :domain
  has_many :cards

  mount_uploader :cover, AssetsUploader
  mount_uploader :logo, AssetsUploader
end
&#13;
&#13;
&#13;

当@subdomain存在没问题时,一切正常,但是当它不存在时,我收到以下错误信息:

NoMethodError in Subdomains#index
undefined method `id' for nil:NilClass
<% if (!@subdomain.id.blank?) %>

我该怎么做才能解决这个问题?感谢

2 个答案:

答案 0 :(得分:3)

快速而肮脏的解决方案是使用#try(不建议使用)

<% if !@subdomain.try(:id).try(:blank?) %>

顺便说一下,您可以使用#present?而不是否定#blank?来使代码更具可读性。

但是,如果我假设正确且@subdomain是ActiveRecord模型,则您无需检查其ID是否存在。在您的情况下,以下代码就足够了:

<% if @subdomain %>
  (...)
<% else %>
  (...)
<% end %>

如果找不到@subdomain,则无论如何都会是nil - 然后if @subdomain条件将被评估为false - 因为nil是一个假值

如果你因为碰巧正在渲染这样的集合而得到这个错误:

= render 'subdomain', collection: @subdomains

...然后你可以把它放在一个条件......

<% if @subdomains.present? %>
  = render 'subdomain', collection: @subdomains
<% else %>
  <% # @subdomains are an empty collection %>
<% end %>

答案 1 :(得分:1)

从您的create action,您的表格中肯定会创建id。我不会理解你想要达到的目的,因为否定#id.blank?

更改视图中的第一行。即。

<% if (!@subdomain.id.blank?) %>

要,

<% if @subdomains %>,它肯定会返回子域表中的所有属性,因为它已在您的索引操作中处理。

我做的另一件事是将我的if...else语句包含在循环中,这样你的视图就变成了:

  <% @subdomains.each do |subd| %>  
         <% if subd.id.present? %> #you can use another attribute here instead of id. e.g. <% if subd.is_published == true %> since `is_published` is a boolean.
             <li>
                (#your codes here referenced with the format called `subd.whatever_attribute`)
             </li>
             <li>
                (#your codes here referenced with the format called `subd.whatever_attribute`)
             </li>
         <% else %>
             <li>Some thing</li>
         <% end %>
   <% end %>