Search code examples
ruby-on-railsruby-on-rails-3mongoidancestry

Unicorn has undefined method error ONLY in production


My app is working great in development mode AND production using WEBrick. But in Unicorn, it only works in development mode. As soon as I try to edit or update a category I get a no method error. Any help is appreciated, Thanks!

Error:

Started GET "/symbols/smoke" for 127.0.0.1 at 2013-04-17 08:06:02 -0700
Processing by CategoriesController#show as JS
  Parameters: {"id"=>"smoke"}
  Rendered layouts/_tabs.html.erb (2.9ms)
  Rendered categories/_meanings.html.haml (0.1ms)
  Rendered categories/_categorylist.html.haml (2.5ms)
  Rendered categories/_show-page.html.haml (13.5ms)
  Rendered categories/show.js.erb (17.1ms)
Completed 500 Internal Server Error in 45ms

ActionView::Template::Error (undefined method `map' for nil:NilClass):
    3:      %li.nav-header a parent of:
    4:      - if @category.has_children?
    5:          
    6:          = list_categories(@children)
    7:      %li
    8:          = link_to new_category_path(:parent_id => @category, :view => "show"), :remote => true do
    9:              Add Child
  app/helpers/categories_helper.rb:21:in `list_categories'
  app/views/categories/_categorylist.html.haml:6:in `_app_views_categories__categorylist_html_haml__3404053025802473956_70332682747260'
  app/views/categories/_show-page.html.haml:48:in `_app_views_categories__show_page_html_haml__1783905832676874426_70332684530780'
  app/views/categories/show.js.erb:8:in `_app_views_categories_show_js_erb___3948970986596034947_70332684487680'
  app/controllers/old_categories.rb:96:in `show'

Categories Controller:

class CategoriesController < ApplicationController
  helper :lego
  helper :meanings

  def index
    @categories = Category.all
    if params[:id]
      @categories = Category.find(params[:id])                      #if params[:id]
      @categories = @categories.children.arrange(:order => 'name')
    elsif params[:view] == "alpha"
      @alphabet   = Category.all.group_by{|c| c.name[0]}
      @see_kids   = false
      @categories = @categories.sort(:name => "ASC")                            if !params[:letter]
      @categories = @categories.where(name: eval("/^#{params[:letter]}/i")).sort(:name => "ASC")     if params[:letter]
    else
      # @categories = Category.all
      @categories = @categories.arrange(:order => 'name')               #if params[:view] != "list"
    end



    respond_to do |format|
      format.html # index.html.erb
      format.js
      format.json { render json: @categories }
    end
  end

  def reorder
    if Rails.env != "production" && !request.xhr?
      flash[:info] = "Currently in #{Rails.env} mode."
    end
    @categories = Category.arrange(:order => 'name')
    @new = Category.new(:parent_id => params[:parent_id])
    @next = Category.count
    respond_to do |format|
      format.html # index.html.erb
      format.js
      format.json { render json: @categories }
    end
  end

  def sort
    params[:category].each do |id, attr|
      thisCat = params[:category][id]
      @category = Category.where(:_id => id).first
      if thisCat.nil? || thisCat == 'null'
        @category.parent_id = nil
        @category.name_tag  = @category.name
      else
        @category.parent_id = thisCat.to_s
        @category.name_tag = "#{@category.name} <small>(#{@category.parent.name})</small>"
      end
      @category.save
    end
  end

  def gallery
    @categories = Category.arrange(:order => 'name')
    @category = Category.find(params[:id])
    @siblings = Category.siblings_of(params[:id])
    respond_to do |format|
      format.html # index.html.erb
      format.js
      format.json { render json: @category }
    end
  end

   def show
     @category    = Category.find(params[:id])
     @updater     = User.find(@category.user) || nil
     get_meanings(@category)
     # @meanings    = @category.meanings 

     respond_to do |format|
       format.html # show.html.erb
       format.js
       format.json { render json: @category }
     end
   end

  def search
    @categories = Category.arrange(:order => 'name')
    @category = Category.find(params[:id])

    @meanings = @category.meanings
    @meanings = @meanings.where(:beliefs => params[:beliefs])         if params[:beliefs]
    @meanings = @meanings.where(:cultures => params[:cultures])       if params[:cultures]
    @meanings = @meanings.where(:connotation => params[:connotation]) if params[:connotation]
    @meanings = @meanings.where(:user => params[:user])               if params[:user]    
  end

  def new
    @new = Category.new(:parent_id => params[:parent_id])
    @form_state   = "new"
    respond_to do |format|
      format.html
      format.js
      format.json
    end
  end

  def edit
    @category = Category.find(params[:id])
    respond_to do |format|
      format.html
      format.js
      format.json
    end
  end

  def create
    @new          = Category.new(params[:category])
    @new.user     = current_user
    @new.name_tag = @new.name
    @new.name_tag = "#{@new.name} <small>#{@new.parent.name}</small>"       if @new.parent

    respond_to do |format|
      if @new.save
        get_meanings(@new)
        flash[:success] = "<h4><i class=icon-ok></i> '#{@new.name}' was successfully created.</h4>"
        format.html { redirect_to @new }
        if session[:form_type] == "show"
          format.js {redirect_to @new }
        else
          format.js
        end
        format.json { render json: @categories, status: :created, location: @new }
      else
        format.html { render action: "new" }
        format.js 
        format.json { render json: @new.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    @categories  = Category.arrange(:order => 'name')
    @category           = Category.find(params[:id])
    @category.user      = current_user 
    @category.name_tag  = params[:category][:name]
    # @siblings           = Category.siblings_of(params[:id])
    @category.name_tag  = "#{params[:category][:name]} <small>#{@category.parent.name}</small>"       if @category.parent
    params[:view]       = "reorder"           if session[:form_type] == "reorder"

    flash[:success] = "<h4><i class=icon-ok></i> #{@category.name} was successfully updated.</h4>"
    get_meanings(@category)
    respond_to do |format|
      # get_meanings(@category)
      # @similar     = Category.where(:name => params[:category][:name])
      if @category.update_attributes(params[:category])
        format.html { redirect_to @category}
        if session[:form_type] == "show"
          format.js #{redirect_to @category }
        else
          format.js 
        end
        format.json { head :no_content }
      else
        # get_meanings(@category)
        flash[:error] = "<h4>Unable to update #{@category.name}</h4>"
        format.html { render action: "edit", error: "Unable to update '#{@category.name}'", status: :unprocessable_entity }
        format.json { render json: @category.errors, status: :unprocessable_entity }
        format.js
      end
    end
  end

  def destroy
    @category = Category.find(params[:id])
    @category.destroy
    flash[:alert] = "<h4><i class=icon-warning-sign></i> Warning. You have deleted the category '#{@category.name}'.</h4>".html_safe
    respond_to do |format|
      format.html { redirect_to categories_url }
      format.json { head :no_content }
      format.js 
    end
  end

  def has_sidebar?
    self.has_children?
  end
private
  def get_meanings(category)
    @categories  = Category.arrange(:order => 'name')
    @children    = category.children.order_by(name: :asc) || []
    @siblings    = category.siblings.order_by(name: :asc) || []
    @similar     = Category.where(:name => category.name) || []
    @meanings    = category.meanings 
    @belief_list    = []
    @culture_list   = []
    @contributors   = []
    @connotations   = []
    for meaning in @meanings
      for belief in meaning.beliefs
        @belief_list << belief 
      end
      for culture in meaning.cultures
        @culture_list << culture
      end
      @connotations << meaning.connotation
      @contributors << meaning.user
    end
    @beliefs      = @belief_list.uniq
    @cultures     = @culture_list.uniq
    @contributors = @contributors.uniq
    @connotations = @connotations.uniq
  end
end

Show Page:

.row
    .span12
        = breadcrumb(@category)
.row
    %section.span10.pull-right
        .row
            %header.span10
                .hero-unit.relative
                    .row
                        - if @category.image?
                            %figure.span3
                                = image_tag @category.image_url

                        .span5
                            %h1
                                = raw @category.name_tag

                            %p= @category.description
                            - if @similar.any?
                                - unless @similar.first.id == @category.id && @similar.last.id == @category.id


                                    See also: 

                                -@similar.each do |ref|
                                    -unless ref.id == @category.id
                                        = link_to raw(ref.name_tag), ref, :remote => true

                            -if @updater
                                .updated-by
                                    Last updated by 
                                    = @updater.name

        .row
            .span10.no-history
                #meaning-controls.row
                    .span2
                        = link_to [:new, @category, :meaning], :class => "btn", remote: true do
                            Add Meaning
                            %i.icon-plus
                    - if @meanings.any?
                        = render 'sorting-hat'
                #meanings.no-history
                    -if @meanings
                        = render 'meanings'

    %aside.span2.float-desktop
        = render 'categorylist'

Helper:

  def list_categories(categories) 
      categories.map do |category|
        content_tag(:li) do
          link_to h(category.name), category, :remote => true
        end
      end.join.html_safe
  end

Update:

Searched through my production.rb file going line by line and found that the line that brings about this error is config.cache_classes = false. As soon as I set it to true it saves normally. Any ideas why this would cause the error?


Solution

  • I turned off config.cache_classes for the time being. The problem has something to do with me not expiring my caches properly. I will figure it out and address it after focusing on cleaning up and re-factoring my code a bit.

    I will update this answer after I start focusing again on caching.