简体   繁体   English

如何重构我的Sinatra应用程序?

[英]How can I refactor my Sinatra app?

I've just started writing a reasonably straightforward site using sinatra. 我刚刚开始使用sinatra编写一个相当简单的网站。 My problem is that I wanted to refactor the main app.rb file but am getting errors trying to access the url params. 我的问题是我想重构主app.rb文件,但是在尝试访问url参数时遇到错误。

In my get '/' action, Sinatra's looking at which params are set and then needs to do a few different things depending on what's in the url. 在我的get'/'操作中,Sinatra正在查看设置了哪些参数,然后需要根据URL中的内容执行一些不同的操作。 Something like this. 这样的事情。

class App < Sinatra::Application
  ...
  get '/' do
    if params['code1']
      @network = 'code1'
      mode code here
    elsif params['called'] && params['mac']
      @network = 'code2'
      mode code here
    elsif params['code3']
      @network = 'code3'
      mode code here
    end  
  end      

The problem is that I need to require a file that also uses the params. 问题是我需要一个也使用参数的文件。

I've put the following in the above code: 我在上面的代码中添加了以下内容:

require File.dirname(__FILE__) + '/lib/networks/code1.rb'

Where code1.rb includes: 其中code1.rb包括:

class App < Sinatra::Application
  if params['login']  # == 'login'
    pass = 'uampass'
  elsif
  ...

But that gives me the following error: 但这给了我以下错误:

undefined local variable or method `params' for main:Object

How can I refactor this without causing an error 我该如何重构而不引起错误

As far as i know you can't use two (or more) Sinatra applications in, well one application. 据我所知,您不能在其中使用两个(或多个)Sinatra应用程序,以及一个应用程序。 Since both files define a Sinatra::Application descendant this isn't possible. 由于两个文件都定义了Sinatra::Application后代,所以这是不可能的。

Also if you want to use values from the params -hash you should define helper methods Helper Documentation , which you call when processing the route, or you just create Class which has class or instance methods which take params-values as parameters. 另外,如果要使用params -hash中的值,则应定义帮助程序方法Helper Documentation ,在处理路由时调用该文件,或者仅创建具有将params-values作为参数的类或实例方法的Class。 Actually calling params from another file/class doesn't seem like good practice. 实际上,从另一个文件/类调用params似乎不是一个好习惯。

To put this in context: Sinatra applications are organised as handlers. 为了说明这一点:Sinatra应用程序被组织为处理程序。 The Sinatra::Application descendant is something like the main handler which uses support methods(helpers and instance methods of the Sinatra::Application descendant) or support Classes, which are usually defined in other files, but do not descend from Sinatra::Application . Sinatra::Application后代类似于处理程序,它使用支持方法( Sinatra::Application后代的帮助器和实例方法)或支持类,它们通常在其他文件中定义,但不从Sinatra::Application

To make this a little bit more clearly: 为了使这一点更加清楚:

Your main Sinatra file: 您的主要 Sinatra文件:

require_relative 'another_file.rb'
class App < Sinatra::Application
  # ...
  @a_handler = MyHandler.new
  get '/' do

    if params['something'] == 'wanted_value'
      @a_handler.handle_it(params)
    end

end

Another file ('another_file.rb'): 另一个文件('another_file.rb'):

class MyHandler
  def initialize
    @an_instance_variable = 'foobar'
  end
  def handle_it(params_hash)
    if params_hash['login']  # == 'login'
      pass = 'uampass'
    elsif
     # ...
    end
    # ...
    # do some stuff
    # ....
    return pass
  end
end

Actual code would of course depend on the real problem you're trying to solve, so if you would elaborate i could be more precise... 实际的代码当然取决于您要解决的实际问题,因此,如果您详细说明一下,我可能会更精确...

The error message contains everything you need to know, and it's nothing to do with Sinatra. 该错误消息包含您需要了解的所有内容,并且与Sinatra无关。

You are requiring code1.rb, which contains this (slightly edited so it will run): 您需要code1.rb,其中包含以下内容(稍作编辑,它将运行):

require 'sinatra'

class App < Sinatra::Application
  if params['login']  # == 'login'
    pass = 'uampass'
  end
end

Ruby evaluates code as it encounters it. Ruby会在遇到代码时对其进行评估。 In this case, you've required 'code1.rb', so it evaluates the code in that file. 在这种情况下,您需要“ code1.rb”,因此它将评估该文件中的代码。 It encounters 'params' and asks "is there a local variable or method with that name?". 它遇到“参数”,并询问“是否存在具有该名称的局部变量或方法?”。 There isn't, so it fails as you've seen. 没有,所以正如您所见,它失败了。 Open an irb session and check it out. 打开一个irb会话并签出。

Class definitions in ruby are just an expression with a scope. ruby中的类定义只是一个带作用域的表达式。

In relation to Sinatra: params is available in the block that a route declaration takes. 关于Sinatra:在路线声明所采用的代码块中可以使用params。

I'd recommend reading Sinatra: Up and Running , which explains some of the 'magic' that is going on (a good companion to the Sinatra Book ). 我建议阅读《 Sinatra:启动和运行》 ,其中解释了一些正在发生的“魔术”( Sinatra Book的一个很好的伴侣)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM