【问题标题】:rails no method error from controller in rails 3 apprails 3 app中的控制器没有方法错误
【发布时间】:2011-08-09 05:18:46
【问题描述】:

我有一个小红宝石应用程序正在运行,但我遇到了一个部分问题。当我调用创建视图时,我使用了一个在发布请求中传递一些参数的表单。我关心的唯一参数是 id 字段,然后我在代码中使用它来在模型中做一些有用的事情。当我尝试从 CREATE 请求中获取新创建的对象并立即在其上调用类方法时,问题就开始了。我为对象创建的类方法称为 create,我想从 initialize 方法调用该方法。当我从 initialize 方法中删除对 create 方法的调用时,一切都运行顺利,这表明我基本上做对了。

POST 请求参数:

{"utf8"=>"✓",
 "authenticity_token"=>"fCQw3Pegyv069jO0tZ4eY5buslyAM/r8yrG7phyoJqI=",
 "id"=>"20110806",
 "commit"=>"Create"}

报告控制器的相关部分

  def create
    @report = Report.new(params[:id], Time.now)
  end

Report 类中的初始化方法,它也是一个模型,并在路由文件中声明为资源,只有 show、new、create 作为控制器操作

class Report
  attr_accessor :date, :file_path, :time_created
  REPORT_DIR = "/home/ben/Desktop"
  date_format = "%Y%m%d"

      def initialize(report_date, timestamp)
        @date = report_date
        @file_path = REPORT_DIR+"/#{date}-orders.txt"
        @time_created = timestamp
        create unless FileTest.exist?(@file_path)
      end

def create
  @orders = ShopifyAPI::Order.find(:all, :params => { :created_at_min => "#{@date} 00:00", :created_at_max => "#{@date} 23:59", :order => "created_at DESC" })

  File.open(@file_path, 'w') { |f| 

    @orders.each do |order|

      # begin line 1
      line1 = "850   00000000000"       # standard way to start the line
      line1 += order.id.to_s            # adding the order id
      oid_len = order.id.to_s.length        # calculating the length of the   order number to
      no_spaces = 22 - oid_len      # place the appropriate number of white space
      no_spaces.times do
        line1 += " "
      end
      line1+= "PO               "       # PO + 15 spaces
      line1+= "PARTNER KEY                   "# this line is 30 chars total, readjust when partner key comes in
      line1+= "0000020552078    0001     004010                     X X401                                        P P"
      f.write (line1+"\n")          # end of line 1

      # begin line 2
      line2 = "850   BEG0020000000NE"       # standard way to start the line
      line2 += order.id.to_s            # add the order id
      no_spaces = 52 - oid_len      # calculate the necessary amount of spaces
      no_spaces.times do
        line2 += " "
      end
      line2 += order.created_at.strftime(date_format) # add the order creation date
      f.write (line2+"\n")          # end of line 2

      # begin line 3
      line3 = "850   DTM017000000"      # standard way to start the line
      line3 += "02"             # standard
      line3 += order.created_at.strftime(date_format)   # order creation date
      f.write (line3+"\n")          # end of line 3

      # begin line 4
      line4 = "850   N1 04700000"       # standard way to start the line
      line4 += "ST "                # standard Ship to qualifier with a space
      full_name = order.customer.first_name+" "+ order.customer.last_name # get the customers full name
      name_len = full_name.length       # determine the length of the name
      no_spaces = 60 - name_len             # to calculate the number of spaces needed
      line4 += full_name
      no_spaces.times do
        line4 += " "
      end
      line4 += "9 "
      line4 += order.customer.id.to_s       # add the customer ID
      f.write (line4+"\n")          # end of line 4

      # begin line 5
      line5 = "850   N3 05000000"       # standard way to start the line
      line5 += order.shipping_address.address1 # add the first line of the billing address
      f.write (line5+"\n")          # end of line 5

      # begin line 6
      line6 = "850   N4 05100000"       # standard way to start the line
      line6 += order.shipping_address.city  # add the city
      city_len = order.shipping_address.city.length # get the length to calculate the needed white space
      no_spaces = 30 - city_len
      no_spaces.times do
        line6 += " "
      end
      line6 += order.shipping_address.province_code # add the province code
      line6 += order.shipping_address.zip   # add the zip/postal code
      f.write (line6+"\n")          # end of line 6

      # begin line 7 (this line repeats per line item)
      line_no = 0               # create a line counter
      order.line_items.each do |line_item|
        line_no = line_no + 1           # increment the line number
        line7 = "850   PO108300000"     # standard way to start the line
        line7 += line_no.to_s           # add the line number to the line
        no_spaces = 20 - line_no.to_s.length    # calculate the number of spaces to append
        no_spaces.times do
          line7 += " "
        end
        no_zeroes = 16 - line_item.quantity.to_s.length # prepend the quantity with zeroes
        no_zeroes.times do
          line7 += "0"
        end
        line7 += line_item.quantity.to_s    # add the quantity to the line
        line7 += "EA"               # standard symbols
        price = '%.2f' % line_item.price    # get the price formatted ##.##
        price_len = price.to_s.length - 1   # figure out how many chars the price is - the decimal
        price.to_s =~ /([0-9]+)\.([0-9]{2})/    # convert the price to a string and break it up
        dollars = $1                # get the dollar amount from the regex
        cents   = $2                        # get the cents amount from the regex
        no_zeroes = 17 - price_len      # calculate the number of zeroes to place after the 2 / before the price
        line7 += "2"                # 2 denotes the position of the decimal in the price
        no_zeroes.times do
          line7 += "0"          # add the zeroes in the middle
        end
        line7 += dollars            # add the dollar amount
        line7 += cents          # add the cent amount
        line7 += "  PI"         # standard symbols
        line7 += line_item.sku.to_s     # add the SKU
        no_spaces = 48 - line_item.sku.to_s.length # calculate the number of spaces needed
        no_spaces.times do
          line7 += " "
        end
        line7 += "VN"               # standard symbols
        line7 += line_item.sku.to_s     # add the SKU again
        f.write (line7+"\n")            
      end                   # end of the line item

      # begin line 8
      line8 = "850   CTT204"
      no_zeroes = 12 - line_no.to_s.length
      no_zeroes.times do
        line8 += "0"
      end
      line8 += line_no.to_s
      f.write(line8+"\n")

      # begin line 9
      line9 = "850   AMT20500000TT 2000000000000058151"
      f.write(line9+"\n")

    end     # end of the order
  }     # closing the file
  @time_created = Time.now
end     # end of create method
end

错误报告:

Started POST "/reports" for 127.0.0.1 at 2011-08-09 02:40:17 -0400
  Processing by ReportsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"fCQw3Pegyv069jO0tZ4eY5buslyAM/r8yrG7phyoJqI=", "id"=>"20110805", "commit"=>"Create"}
Completed 500 Internal Server Error in 9ms

NoMethodError (undefined method `path' for nil:NilClass):
  app/models/report.rb:35:in `create'
  app/models/report.rb:10:in `initialize'
  app/controllers/reports_controller.rb:8:in `new'
  app/controllers/reports_controller.rb:8:in `create'

【问题讨论】:

  • 你能发布你的报告控制器吗?
  • @Devin M 感谢您的浏览,我已添加。
  • 你在哪里定义REPORT_DIR?它的代码是什么样的?
  • @Devin M 甚至将报告目录行更改为:file_path = "#{REPORT_DIR}/#{date}-orders.txt" 同样的问题
  • @Bnjmn 这很酷,但现在的问题是错误消息与您发布的代码不匹配。请检查app/models/report.rb:35 是对@orders = ShopifyAPI::Order.find... 的调用。如果是,我建议插入一些 logger.debug 消息,以便您检查是否传递了您认为的值。

标签: ruby-on-rails model-view-controller


【解决方案1】:

另一个猜测...

您以 yyyymmdd hh:mm 格式向 Shopify API 传递日期,但 API documentation 要求以 yyyy-mm-dd hh:mm 格式提供日期。

还要注意您的 date_format 类变量对您的实例方法不可见(建议将其设为 CONSTANT)。

【讨论】:

  • 优秀的 cmets,谢谢 Rob。两者都实施了,他们提供了帮助。
【解决方案2】:

是这样吗:

@file_path = REPORT_DIR+"/#{@date}-orders.txt"

您可能缺少日期的 @ 符号。

您可能还想尝试使用提供的方法访问中午和午夜。

@date.midnight
@date.midnight + 12.hours # or is it - 12.hours ?

【讨论】:

  • 其实我不明白这可以如何解决你的错误,但也许它可能是问题的一部分。我没有看到从任何地方调用路径。如果可能的话,你能告诉我们哪一行是 35 吗?
  • 第 35 行:订单 = ShopifyAPI::Order.find(:all, :params => { :created_at_min => "#{date} 00:00", :created_at_max => "#{date } 23:59", :order => "created_at DESC" })
  • "...Ruby 比这更宽容..."。并不真地。 date@date 是两个不同的变量。
  • 不确定它是否能解决您的问题,但我添加了更多建议,我仍然不知道导致错误的调用路径是什么。如果错误发生变化,请更新我们。
【解决方案3】:

我发现了问题。由于该应用程序在 shopify 应用程序的框架内工作,因此报告控制器需要一个额外的方法来确保用户在向 API 发出请求之前经过身份验证。非常 Shopify 的具体问题,感谢大家的参与。没有您的帮助,我将无处可去,感谢您帮助我推理。

【讨论】:

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