未定义的方法`count'为零:NilClass rails

时间:2017-10-18 09:02:00

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 rubygems

我正在尝试在我的房间列表中设置照片上传部分。当我尝试点击照片时出现此错误

undefined method 'count' for nil:NilClass rails <% if @photos.count > 0 %>

我添加了photo_upload.html.erb页面和a _room_menu部分,但我仍然收到错误消息。

这是我的代码:

photos_controller.rb

       class PhotosController < ApplicationController
        def create
          @room = Room.find(params[:room_id])
          if params[:images]
            params[:images].each do |img|
              @room.photos.create(image:img)
            end
            @photos = @room.photos
            redirect_back(fallback_location:request.referer, notice: "Saved...")
        end
      end


    end

**views/rooms/photo_upload.html.erb**

<div class="row">
  <div class="col-md-3">
    <%= render 'room_menu' %>
  </div>
  <div class="col-md-9">
    <div class="panel panel-default">

      <div class="panel-heading">
        Photos
      </div>

      <div class="panel-body">
        <div class="container">
          <div class="row">
            <div class="col-md-offset-3 col-md-6">
              <!-- PHOTOS UPLOAD GOES HERE -->

              <%= form_for @room, url: room_photos_path(@room), method: 'post', html: {multipart: true} do |f| %>
                <div class="row">
                  <div class="form-group">
                    <span class="btn btn-default btn-file text-babu">
                      <i class="fa fa-cloud-upload" aria-hidden="true"></i> Select Photos
                      <%= file_field_tag "images[]", type: :file, multiple: true %>
                    </span>
                  </div>
                </div>

                <div class="text-center">
                  <%= f.submit "Add Photos", class: "btn btn-form" %>
                </div>

              <% end %>
            </div>
          </div>

          <div id="photos"><%= render 'photos/photos_list' %></div>
        </div>
      </div>

    </div>
  </div>
</div>

视图/房间/ _room_menu.html.erb

<ul class="sidebar-list">
  <li class="sidebar-item">
    <%= link_to "Listing", listing_room_path, class: "sidebar-link active" %>
    <span class="pull-right text-babu"><i class="fa fa-check"></i></span>
  </li>
  <li class="sidebar-item">
    <%= link_to "Pricing", pricing_room_path, class: "sidebar-link active" %>
    <% if !@room.price.blank? %>
      <span class="pull-right text-babu"><i class="fa fa-check"></i></span>
    <% end %>
  </li>
  <li class="sidebar-item">
    <%= link_to "Description", description_room_path, class: "sidebar-link active" %>
    <% if !@room.listing_nam.blank? %>
      <span class="pull-right text-babu"><i class="fa fa-check"></i></span>
    <% end %>
  </li>

    <li class="sidebar-item">
    <%= link_to "Photos", photo_upload_room_path, class: "sidebar-link active" %>
    <% if !@room.photos.blank? %>
      <span id="photo_check" class="pull-right text-babu"><i class="fa fa-check"></i></span>
    <% end %>
  </li>

  <li class="sidebar-item">
    <%= link_to "Amenities", amenities_room_path, class: "sidebar-link active" %>
    <span class="pull-right text-babu"><i class="fa fa-check"></i></span>
  </li>
  <li class="sidebar-item">
    <%= link_to "Location", location_room_path, class: "sidebar-link active" %>
    <% if !@room.address.blank? %>
      <span class="pull-right text-babu"><i class="fa fa-check"></i></span>
    <% end %>
  </li>
</ul>
<hr/>

3 个答案:

答案 0 :(得分:3)

你无法在零上呼叫.count。必须首先实例化@photos。您的控制器似乎根本没有实例化@photos。我无法在您的代码中看到您调用@photos的其他位置,但在调用它的地方,尚未定义实例变量。您的控制器创建方法仅显示在params[:images]存在时发生,否则它将为零。 尝试在if块之外实例化@photos。

def create
  @room = Room.find(params[:room_id])
  @photos = @room.photos
  if params[:images]
    params[:images].each do |img|
      @room.photos.create(image: img)
    end
    redirect_back(fallback_location:request.referer, notice: "Saved...")
  end
end

更新:Ruby 2.3+您可以使用&安全导航:

def create
  @room = Room.find(params[:room_id])
  params[:images]&.each{|img| @room.photos.create(image: img)}
  redirect_back(fallback_location: request.referer, notice: "Saved...")
end

或者,当您应该只能在其中调用@photos时,为什么还要在视图中使用单独的@room.photos

不要在视图中调用.count作为条件,而是使用@room.photos.present?

还有一个建议是优先使用肯定的if案例。所以改变

if !@room.photos.blank?
# better to use this below
if @room.photos.present?

此外,假设在创建操作之前,您需要在控制器中执行一个新操作,如果确实需要将@photos@room.photos隔离,则需要定义{{1}}。这是rails中的标准MVC,但不确定您是否正确发布了所有代码,所以我在这里猜测。

答案 1 :(得分:2)

上面的人已经给出了很好的解释,为什么你不能在零课上调用方法。此外,以下代码可能对您的情况有所帮助:

<% if !@photos.nil? && @photos.count > 0 %>

答案 2 :(得分:1)

<% if @photos.count > 0 %>

如果因为nil class&#39;的错误未定义方法失败,则表示@photos为nil,因此您无法对其执行任何方法。你在哪里叫它?您尚未将其包含在代码中。

当您单击该链接时,请查看您的服务器日志,它将告诉您正在执行哪个控制器操作。无论您采取何种行动,都需要定义@photos。

如果是照片#create(上面列出的控制器动作)则表示@ room.photos为零。这是不可能的,因为它几乎肯定会返回一个空的活动记录关系,如果有的话,所以你的问题不是在控制器中定义@photos和你当时正在使用的动作。