【问题标题】:Rails 4: unable to view the show page in herokuRails 4:无法在heroku中查看显示页面
【发布时间】:2014-10-13 14:49:42
【问题描述】:

我的餐厅评论应用程序在 Localhost 中运行,但是当我在 heroku 上尝试此操作并单击链接以显示我收到的评论时,很抱歉,但出了点问题。 heroku 日志显示以下错误信息 ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):

2014-08-20T09:32:49.175203+00:00 app[web.1]:     46:                <h4>
2014-08-20T09:32:49.175221+00:00 app[web.1]:     49:                <p><%= review.created_at.strftime("%-m/%-d/%y") %></p>
2014-08-20T09:32:49.175223+00:00 app[web.1]:     50:                </td>
2014-08-20T09:32:49.175225+00:00 app[web.1]:   app/views/restaurants/show.html.erb:47:in `block in _app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175226+00:00 app[web.1]:   app/views/restaurants/show.html.erb:43:in `_app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175303+00:00 app[web.1]:     48:                </h4>
2014-08-20T09:32:49.175229+00:00 app[web.1]: 
2014-08-20T09:32:49.175284+00:00 app[web.1]: ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.175307+00:00 app[web.1]:   app/views/restaurants/show.h
tml.erb:47:in `block in _app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175298+00:00 app[web.1]:     45:                <td>
2014-08-20T09:32:49.175199+00:00 app[web.1]: ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.175282+00:00 app[web.1]: 
2014-08-20T09:32:49.175304+00:00 app[web.1]:     49:                <p><%= review.created_at.strftime("%-m/%-d/%y") %></p>
2014-08-20T09:32:49.175309+00:00 app[web.1]:   app/views/restaurants/show.html.erb:43:in `_app_views_restaurants_show_html_erb__3540437068917616550_70094864076860'
2014-08-20T09:32:49.175300+00:00 app[web.1]:     46:                <h4>
2014-08-20T09:32:49.175218+00:00 app[web.1]:     47:                <%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>
2014-08-20T09:32:49.175301+00:00 app[web.1]:     47:                <%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>
2014-08-20T09:32:49.175310+00:00 app[web.1]: 
2014-08-20T09:32:49.175305+00:00 app[web.1]:     50:                </td>
2014-08-20T09:32:49.175312+00:00 app[web.1]: 
2014-08-20T09:32:49.626763+00:00 heroku[router]: at=info method=GET path="/restaurants/5" host=yelpdemo2014.herokuapp.com request_id=76387447-eb34-431b-9fcf-785a901e95ee fwd="185.30.24.132" dyno=web.1 connect=1ms service=58ms status=500 bytes=1030
2014-08-20T09:32:49.580600+00:00 app[web.1]:   Parameters: {"id"=>"5"}
2014-08-20T09:32:49.580595+00:00 app[web.1]:   Parameters: {"id"=>"5"}
2014-08-20T09:32:49.617957+00:00 app[web.1]:   Rendered restaurants/show.html.erb within layouts/application (20.7ms)
2014-08-20T09:32:49.617970+00:00 app[web.1]:   Rendered restaurants/show.html.erb within layouts/application (20.7ms)
2014-08-20T09:32:49.620207+00:00 app[web.1]: Completed 500 Internal Server Error in 37ms
2014-08-20T09:32:49.622252+00:00 app[web.1]: ActionView::Template::Error (undefined method `capitalize' for nil:NilClass):
2014-08-20T09:32:49.580536+00:00 app[web.1]: Processing by RestaurantsController#show as HTML
2014-08-20T09:32:49.620214+00:00 app[web.1]: Completed 500 Internal Server Error in 37ms
2014-0

show.html

div class="row">
    <div class="col-md-3">
        <%= image_tag @restaurant.image_url %>

<h2>
  <%= @restaurant.name %>
</h2>

<div class="star-rating" data-score= <%= @avg_rating %> ></div>
<p><%= "#{@reviews.length} reviews" %></p>

<p>
  <strong>Address:</strong>
  <%= @restaurant.address %>
</p>

<p>
  <strong>Phone:</strong>
  <%= @restaurant.phone %>
</p>

<p>
  <strong>Website:</strong>
  <%= link_to @restaurant.website, @restaurant.website %>
</p>

    <%= link_to 'Write a review', new_restaurant_review_path(@restaurant), class: "btn btn-primary" %>

</div>

    <div class="col-md-9">
        <% if @reviews.blank? %>
            <h3>No reviews yet, be the first to write one!</h3>
        <% else %>
            <table class="table">
                <thead>
                    <tr>
                        <th class="col-md-3"></th>
                        <th class="col-md-9"></th>
                    </tr>
                </thead>
                <tbody>
                    <% @reviews.each do |review| %>
                    <tr>
                        <td>
                            <h4>
                                <%= "#{review.user.first_name.capitalize} #{review.user.last_name.capitalize[0]}." %>
                            </h4>
                            <p><%= review.created_at.strftime("%-m/%-d/%y") %></p>
                        </td>
                        <td>
                            <div class="star-rating" data-score= <%= review.rating %> ></div>
                            <p><%= h(review.comment).gsub(/\n/, '<br/>').html_safe %></p>
                        </td>
                    </tr>
                <% end %>
            </tbody>
        </table>
    <% end %>
    </div>
</div>

<%= link_to 'Edit', edit_restaurant_path(@restaurant), class: "btn btn-link" %> |
<%= link_to 'Back', restaurants_path, class: "btn btn-link" %>

<script>
    $('.star-rating').raty({
        path: 'https://s3-eu-west-1.amazonaws.com/yelpdemoneil/stars',
        readOnly: true,
        score: function() {
        return $(this).attr('data-score');
  }
});
</script>

餐厅管理员

class RestaurantsController < ApplicationController
  before_action :set_restaurant, only: [:show, :edit, :update, :destroy]


  # GET /restaurants
  # GET /restaurants.json
  def index
    @restaurants = Restaurant.all
  end

  # GET /restaurants/1
  # GET /restaurants/1.json
  def show
    @reviews = Review.where(restaurant_id: @restaurant.id).order("created_at DESC")
    if @reviews.blank?
      @avg_rating = 0
    else
      @avg_rating = @reviews.average(:rating).round(2)
    end
  end

  # GET /restaurants/new
  def new
    @restaurant = Restaurant.new
  end

  # GET /restaurants/1/edit
  def edit
  end

  # POST /restaurants
  # POST /restaurants.json
  def create
    @restaurant = Restaurant.new(restaurant_params)


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

  # PATCH/PUT /restaurants/1
  # PATCH/PUT /restaurants/1.json
  def update
    respond_to do |format|
      if @restaurant.update(restaurant_params)
        format.html { redirect_to @restaurant, notice: 'Restaurant was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @restaurant.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /restaurants/1
  # DELETE /restaurants/1.json
  def destroy
    @restaurant.destroy
    respond_to do |format|
      format.html { redirect_to restaurants_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_restaurant
      @restaurant = Restaurant.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def restaurant_params
      params.require(:restaurant).permit(:name, :address, :phone, :website, :image)
    end
end

【问题讨论】:

    标签: ruby-on-rails heroku


    【解决方案1】:

    错误在这里:

    ActionView::Template::Error (undefined method `capitalize' for nil:NilClass)
    

    问题是您在未设置的 variable / object 上调用方法。正如您提到它只显示在 Heroku 上,我想说这是由于您的数据库中没有所需的记录引起的

    解决这个问题很简单:

    <% if @reviews.any? %>
       <% @reviews.each do |review| %>
          ...
       <% end %>
    <% end %>
    

    --

    数据

    最重要的是,您需要在数据库中拥有数据才能填充您希望在应用程序中显示的各种变量/对象

    很多人的问题是 Heroku 没有维护与本地系统相同的数据库,因此如果您希望数据存在,但实际上没有,您的系统将调用您遇到的异常看到

    最重要的是,您需要进行一些验证(以确定您需要的数据是否存在),或者您需要 seed your production database 提供您的应用程序所需的记录

    【讨论】:

    • 感谢您花时间详细解释您的解决方案,干杯 Neil
    • 顺便说一句,在迭代(或使用)您怀疑其中可能包含 nil、空字符串等的数组时,您可以使用 my_array.reject(&amp;:blank?) 忽略空白值。在这种情况下,它不会尝试迭代等于nil 的@reviews 值,如果@reviews 中没有非空值,那么它根本不会迭代。
    • 另外,my_array.reject!(&amp;:blank?)(注意!)将从数组中永久删除空白值。
    【解决方案2】:

    我同意 Rich 的观点,这是另一种解决方法:

    我将try 用于“名字”等可选属性,因为我不想强迫用户通过验证来提交它们:

    <%= "#{review.user.first_name.try(:capitalize)} #{review.user.last_name.try(:capitalize)}." %>
    

    这样它不应该抛出异常,无论是否有属性

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多