使用NameError未初始化的常量调试数据库查询

时间:2014-04-25 03:12:06

标签: ruby-on-rails ruby postgresql

我在我的Ruby on rail网站上有以下查询。我是Ruby on Rails的新手,并且自学了这个编码。我知道的php有很多不同。

我编辑的原始行是:(但我需要它从另一个表中拉出来。)

  Module.const_get(self.search_type.capitalize).where(where).select(select).limit(limit).order(order).page(page).per_page(10)

我的问题是如何启动Follow Constant变量。或重新编程使其工作?

我收到以下错误:

Started GET "/searches/23795" for 50.83.98.168 at 2014-04-24 22:00:54 -0500
2014-04-24 22:00:54 INFO -- Processing by SearchesController#show as HTML
2014-04-24 22:00:54 INFO --   Parameters: {"id"=>"23795"}
2014-04-24 22:01:01 INFO -- Completed 500 Internal Server Error in 6716ms
2014-04-24 22:01:01 FATAL -- 
NameError (uninitialized constant Search::Hotloads):
  app/models/search.rb:62:in `search'
  app/controllers/searches_controller.rb:41:in `show'

我们的数据库表名是" hotloads"

  def searches(page)
    where = []
    where << PrepareSearch.states("dest", self.dest_states) unless self.dest_states.blank?
    where << PrepareSearch.date('created_at', self.date_posted, '>=') unless self.date_posted.blank?
    if self.search_type == 'load'
      select = "loads.id, origin, dest, pickup, delivery, ltl, equipment_id, weight, length, rate"
      where << PrepareSearch.attribute('ltl', self.ltl, '=') unless self.ltl.blank?
    elsif self.search_type == 'truck'
      select = "trucks.id, origin, dest, available, expiration, equipment_id, comments"
      where << PrepareSearch.date('available',self.available,self.available_operator) unless self.available.blank?
self.expiration.blank?
    end
    where << "covered=false AND deleted=false"
    where = where.join(' AND ')
    order = self.order_by ? self.order_by + " desc" : ""
    limit = "LIMIT=200"
      Hotloads.where(where).select(select).limit(limit).order(order).page(page).per_page(5)
  end

更新

如果我将此行更改为此

Module.Hotloads.where(where).select(select).limit(limit).order(order).page(page).per_page(5)

我收到此错误

Started GET "/searches/23795" for 50.83.98.168 at 2014-04-24 22:14:15 -0500
2014-04-24 22:14:16 INFO -- Processing by SearchesController#show as HTML
2014-04-24 22:14:16 INFO --   Parameters: {"id"=>"23795"}
2014-04-24 22:14:20 INFO -- Completed 500 Internal Server Error in 3913ms
2014-04-24 22:14:20 FATAL -- 
NoMethodError (undefined method `Hotloads' for Module:Class):
  app/models/search.rb:94:in `searches'
  app/controllers/searches_controller.rb:42:in `show'

请求控制器

class SearchesController < ApplicationController
  load_and_authorize_resource
  attr_accessor :log

  def new
    @search = Search.new
  end

  def edit
    @search = Search.find(params[:id])
    @search.origin_cs = @search.origin.cs unless @search.origin.nil?
    @search.dest_cs = @search.dest.cs unless @search.dest.nil?
    %w[pickup delivery available expiration].each do |date| 
      date = date.to_sym
      @search[date] = @search[date].strftime("%F") unless @search[date].blank?
    end
  end

  def create
    @search = Search.new(params[:search])
    if @search.save
      redirect_to @search
    else
      render 'new'
    end
  end

  def update
    @search = Search.find(params[:id])

    if @search.update_attributes(params[:search])
      redirect_to @search
    else
      render 'edit'
    end
  end

  def show
    @search = Search.find(params[:id])
    @searches = Search.find(params[:id])
    @results = @search.search(params[:page])
    @resultss = @searches.searches(params[:page])
    @search.update_attribute(:results, @results.count)
    @searches.update_attribute(:resultss, @resultss.count)
    respond_to do |format|
      format.html 
      format.js {render "results"}
      format.js {render "resultss"}
    end
  end

  def load_search
    @search = Search.new
    @user_id = params[:user_id]
    respond_to do |format|
      format.html { raise "Unsupported" }
      format.js
    end
  end

  def truck_search
    @search = Search.new
    @user_id = params[:user_id]
    respond_to do |format|
      format.html { raise "Unsupported" }
      format.js
    end
  end

  def recent_search
    @user_id = params[:user_id] || current_user.id
    @searches = Search.includes(:origin, :dest).where(user_id: @user_id).limit(15).order("searches.updated_at desc")
    respond_to do |format|
      format.html { render "_recent_search", locals: {user_id: @user_id, searches: @searches} }
      format.js
    end
  end

  def saved_search
    @user_id = params[:user_id] || current_user.id
    @searches = Search.includes(:origin, :dest).where(user_id: @user_id, saved: true).order("searches.updated_at desc").page(params[:saved_search]).limit(15).per_page(15)
    respond_to do |format|
      format.html { render "_saved_search", locals: {user_id: @user_id, searches: @searches} }
      format.js
    end
  end

  def ezsearch
    @user_id = params[:user_id]
    respond_to do |format|
      format.html { raise "Unsupported" }
      format.js
    end
  end

  def states
    results = []
    JSON(AUTOCOMPLETE_STATES).each {|state| results << state if (state["name"].downcase.include?(params[:q]) or state["id"].downcase.include?(params[:q]))}
    respond_to do |format|
      format.json { render json: (JSON.dump results)}
    end
  end

  def convert
   @search_params = Search.find(params[:search_id])
   if @search_params.search_type == "truck"
     redirect_to :controller => "trucks", :action => "new", :search_id => params[:search_id]
   else
     redirect_to :controller => "loads", :action => "new", :search_id => params[:search_id]
   end
  end

  @log = Logger.new("#{Rails.root}/log/searches.log")
  @log.datetime_format = "%F %T"
end

搜索模型

class Search < ActiveRecord::Base
  attr_accessible :available, :delivery, :dest, :length, :ltl, :origin, :pickup, :rate, :search_type, :user_id, :weight, :expiration, :pickup_operator, :delivery_operator, :expiration_operator, :available_operator, :length_operator, :rate_operator, :weight_operator, :origin_zip, :dest_zip, :origin_radius, :dest_radius, :saved, :date_posted, :order_by, :origin_cs, :results, :resultss, :dest_cs, :origin_states, :dest_states, :origin_id, :dest_id, :equipment_ids, :temp_origin, :temp_dest, :temp_equipment
  attr_accessor :origin_cs, :dest_cs, :log
  before_validation :convert_cs_to_id

  OPERATORS = ["<=","<",">=",">","=","!="]
  NUMERICALITY_MESSAGE = "Needs to be a number"
  LOCATION_FORMAT_MESSAGE = "Location must be in format (city,ST)"
  LOCATION_PRESENCE_MESSAGE = "Location does not exist"
  validates_inclusion_of :pickup_operator, in: OPERATORS
  validates_inclusion_of :delivery_operator, in: OPERATORS
  validates_inclusion_of :expiration_operator, in: OPERATORS
  validates_inclusion_of :available_operator, in: OPERATORS
  validates_inclusion_of :length_operator, in: OPERATORS
  validates_inclusion_of :rate_operator, in: OPERATORS
  validates_inclusion_of :weight_operator, in: OPERATORS
  validates_inclusion_of :search_type, in: ["load","truck"]
  validates_numericality_of :rate, {allow_nil: true, message: NUMERICALITY_MESSAGE}
  validates_numericality_of :origin_radius,{allow_nil: true, message: NUMERICALITY_MESSAGE}
  validates_numericality_of :dest_radius, {allow_nil: true, message: NUMERICALITY_MESSAGE}
  validates_numericality_of :weight, allow_nil: true, message: NUMERICALITY_MESSAGE
  validates_numericality_of :length, allow_nil: true, message: NUMERICALITY_MESSAGE
  validates_presence_of :search_type
  validates_presence_of :origin_id, :if => :origin_cs?
  validates_presence_of :dest_id, :if => :dest_cs?

  belongs_to :user
  has_and_belongs_to_many :equipment
  belongs_to :origin, class_name: "Location", foreign_key: :origin_id
  belongs_to :dest, class_name: "Location", foreign_key: :dest_id



  def search(page)
    where = []
    where << PrepareSearch.states("dest", self.dest_states) unless self.dest_states.blank?
    where << PrepareSearch.states("origin", self.origin_states) unless self.origin_states.blank? 
    where << PrepareSearch.location('origin', self.origin.coords, self.origin_radius) unless self.origin.blank?
    where << PrepareSearch.location('origin', self.origin.coords, self.origin_radius) unless self.origin.blank?
    where << PrepareSearch.zip('origin', self.origin_zip, self.origin_radius) unless self.origin || self.origin_zip.blank?
    where << PrepareSearch.location('dest', self.dest.coords, self.dest_radius) unless self.dest.blank? 
    where << PrepareSearch.zip('dest', self.dest_zip, self.dest_radius) unless self.dest || self.dest_zip.blank?
    where << PrepareSearch.equipment(self.equipment_ids) unless self.equipment_ids.blank?
    where << PrepareSearch.date('created_at', self.date_posted, '>=') unless self.date_posted.blank?
    if self.search_type == 'load'
      select = "loads.id, origin, dest, pickup, delivery, ltl, equipment_id, weight, length, rate"
      where << PrepareSearch.date('pickup', self.pickup, self.pickup_operator) unless self.pickup.blank?
      where << PrepareSearch.date('delivery', self.delivery, self.delivery_operator) unless self.delivery.blank?
      where << PrepareSearch.attribute('length', self.length, self.length_operator) unless self.length.blank?
      where << PrepareSearch.attribute('rate', self.rate, self.rate_operator) unless self.rate.blank?
      where << PrepareSearch.attribute('weight', self.weight, self.weight_operator) unless self.weight.blank?
      where << PrepareSearch.attribute('ltl', self.ltl, '=') unless self.ltl.blank?
    elsif self.search_type == 'truck'
      select = "trucks.id, origin, dest, available, expiration, equipment_id, comments"
      where << PrepareSearch.date('available',self.available,self.available_operator) unless self.available.blank?
      where << PrepareSearch.date('expiration',self.expiration,self.expiration_operator) unless self.expiration.blank?
    end
    where << "covered=false AND deleted=false"
    where = where.join(' AND ')
    order = self.order_by ? self.order_by + " desc" : ""
    limit = "LIMIT=200"
      Module.const_get(self.search_type.capitalize).where(where).select(select).limit(limit).order(order).page(page).per_page(10)
  end


  def searches(page)
    where = []
    where << PrepareSearch.states("dest", self.dest_states) unless self.dest_states.blank?
    where << PrepareSearch.states("origin", self.origin_states) unless self.origin_states.blank? 
    where << PrepareSearch.location('origin', self.origin.coords, self.origin_radius) unless self.origin.blank?
    where << PrepareSearch.location('origin', self.origin.coords, self.origin_radius) unless self.origin.blank?
    where << PrepareSearch.zip('origin', self.origin_zip, self.origin_radius) unless self.origin || self.origin_zip.blank?
    where << PrepareSearch.location('dest', self.dest.coords, self.dest_radius) unless self.dest.blank? 
    where << PrepareSearch.zip('dest', self.dest_zip, self.dest_radius) unless self.dest || self.dest_zip.blank?
    where << PrepareSearch.equipment(self.equipment_ids) unless self.equipment_ids.blank?
    where << PrepareSearch.date('created_at', self.date_posted, '>=') unless self.date_posted.blank?
    if self.search_type == 'load'
      select = "loads.id, origin, dest, pickup, delivery, ltl, equipment_id, weight, length, rate"
      where << PrepareSearch.date('pickup', self.pickup, self.pickup_operator) unless self.pickup.blank?
      where << PrepareSearch.date('delivery', self.delivery, self.delivery_operator) unless self.delivery.blank?
      where << PrepareSearch.attribute('length', self.length, self.length_operator) unless self.length.blank?
      where << PrepareSearch.attribute('rate', self.rate, self.rate_operator) unless self.rate.blank?
      where << PrepareSearch.attribute('weight', self.weight, self.weight_operator) unless self.weight.blank?
      where << PrepareSearch.attribute('ltl', self.ltl, '=') unless self.ltl.blank?
    elsif self.search_type == 'truck'
      select = "trucks.id, origin, dest, available, expiration, equipment_id, comments"
      where << PrepareSearch.date('available',self.available,self.available_operator) unless self.available.blank?
      where << PrepareSearch.date('expiration',self.expiration,self.expiration_operator) unless self.expiration.blank?
    end
    where << "covered=false AND deleted=false"
    where = where.join(' AND ')
    order = self.order_by ? self.order_by + " desc" : ""
    limit = "LIMIT=200"
      Module.Hotloads.where(where).select(select).limit(limit).order(order).page(page).per_page(5)
  end

  module PrepareSearch
    def PrepareSearch.equipment(equipments)
      eq = ""
      equipments.each {|e| eq += "'#{e}'," }
      eq = eq[0..-2]
      "equipment_id IN (#{eq})"
    end

    def PrepareSearch.attribute(attribute, value, comparison)
      "#{attribute} #{comparison} #{value}"
    end

    def PrepareSearch.date(type, date, comparison)
      if comparison == '='
        "CAST(#{type} as TEXT) LIKE '%#{date.strftime("%F")}%'"
      elsif comparison == '<='
        "#{type} #{comparison} '#{date.strftime("%F")} 23:59:59'"
      else
        "#{type} #{comparison} '#{date.strftime("%F")}'"
      end
    end

    def PrepareSearch.zip(type, zip, radius)
      location = Location.where(zip: zip).first
      if location
        "(ST_Distance(#{type}, ST_GeographyFromText('POINT( #{location.coords.x} #{location.coords.y} )')) <= #{radius.to_f*1609.334})"
      else
        #if no locations match zip search for location that will never exist.
        "(ST_Distance(#{type}, ST_GeographyFromText('POINT( 1 1 )')) <= #{radius.to_f*1609.334})"
      end
    end

    def PrepareSearch.location(type, location, radius)
      "(ST_Distance(#{type}, ST_GeographyFromText('POINT( #{location.x} #{location.y} )')) <= #{radius.to_f*1609.334})"
    end

    def PrepareSearch.states(type, states)
      states = states.split(",")
      st = ""
      states.each {|s| st += "'#{s}'," }
      st = st[0..-2]
      "#{type}_state IN (#{st})"
    end
  end

  @log = Logger.new("#{Rails.root}/log/searches.log")
  @log.datetime_format = "%F %T"

  private

    def convert_cs_to_id
      temp_origin = Location.where(cs: self.origin_cs.downcase) unless self.origin_cs.blank?
      self.origin_id = temp_origin.blank? ? "" : temp_origin.first.id

      temp_dest = Location.where(cs: self.dest_cs.downcase) unless self.dest_cs.blank?
      self.dest_id = temp_dest.blank? ? "" : temp_dest.first.id
    end

    def origin_cs?
      errors.add(:origin_cs, "not a valid location") if !origin_cs.blank? && origin_id.blank?
      origin_cs.blank? ? false : true
    end

    def dest_cs?
      errors.add(:dest_cs, "not a valid location") if !dest_cs.blank? && dest_id.blank?
      dest_cs.blank? ? false : true
    end
end

1 个答案:

答案 0 :(得分:1)

我认为你应该只在查询时关注:

  Hotloads.where(where).select(select).limit(limit).order(order).page(page).per_page(5)

as,我猜,Module.const_get(self.search_type.capitalize)必须返回活动记录模型进行搜索,如果您的数据库表名称为ActiveRecord,则必须另外注明par hotloads约定,相应的班级名称将为Hotload,因此在这种情况下,您的查询将如下:Hotload.where(where).select(select)...