2012-06-28 33 views
1

我有一个应用程序文件,看起来像这样ws_app.rb:屈+机架路由

require 'rubygems' 
require 'sinatra' 
require 'sinatra/respond_to' 
require 'dm-core' 
require 'dm-migrations' 
require 'dm-timestamps' 
require 'json' 
require 'csv' 

load 'models/Battery.rb' 

Sinatra::Application.register Sinatra::RespondTo 
DataMapper::setup(:default,"sqlite3://#{Dir.pwd}/mpt_hmi.sqlite3") 

class MPTHMI < Sinatra::Base 

    load 'controller/BatteryController.rb' 

end 

模块/ Battery.rb看起来像这样:

class Battery 
    include DataMapper::Resource 

    property :id, Serial 
    property :i_battery_manager_id, Integer 
    property :c_battery_number, String 
    property :c_battery_state, String 
    property :c_voltage_byte, String 
    property :i_voltage_int, Integer 
    property :i_temperature, Integer 
    property :i_resistance, Integer 
    property :i_capacity, Integer 
    property :i_cell_balancing_duration, Integer 
    property :i_total_cell_balancing_duration, Integer 
    property :i_age, Integer 
    property :i_time_to_service, Integer 
    property :created_at, DateTime 
    property :updated_at, DateTime 

    def to_my_json 
    { 
     :i_battery_manager_id => self.i_battery_manager_id, 
     :c_battery_number => self.c_battery_number, 
     :c_battery_state => self.c_battery_state, 
     :c_voltage_byte => self.c_voltage_byte, 
     :i_voltage_int => self.i_voltage_int, 
     :i_temperature => self.i_temperature, 
     :i_resistance => self.i_resistance, 
     :i_capacity => self.i_capacity, 
     :i_cell_balancing_duration => self.i_cell_balancing_duration, 
     :i_total_cell_balancing_duration => self.i_total_cell_balancing_duration, 
     :i_age => self.i_age, 
     :i_time_to_service => self.i_time_to_service 
    } 
    end 

end 

控制器/ BatteryController.rb文件看起来像这样:

get '/battery/:id' do 
    @battery = Battery.get(params[:id]) 
    respond_to do |wants| 
    wants.html { erb :battery } # html 
    wants.json { @battery.to_my_json.to_s } # json 
    end 
end 

get '/batteries' do 
    @batteries = Battery.all 
    respond_to do |wants| 
    wants.html { erb :batteries } # html 
    wants.json { 
     @batteries.all.inject({}) { |hsh, obj| 
     hsh[obj.id] = obj.to_my_json 
     hsh 
     }.to_json 
    } 
    end 
end 

这工作完全当我运行正常西纳特拉,就像这样:

$ ruby ws_app.rb 
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from Thin 
>> Thin web server (v1.3.1 codename Triple Espresso) 
>> Maximum connections set to 1024 
>> Listening on 0.0.0.0:4567, CTRL+C to stop 

然后去这里:

http://0.0.0.0:4567/battery/5.json 

我得到我期待的JSON:

{:i_battery_manager_id=>1, :c_battery_number=>"5", :c_battery_state=>"3", :c_voltage_byte=>"145", :i_voltage_int=>191, :i_temperature=>107, :i_resistance=>81, :i_capacity=>228, :i_cell_balancing_duration=>127, :i_total_cell_balancing_duration=>37, :i_age=>111, :i_time_to_service=>211} 

,但我需要一个切诺基Web服务器上部署这一点,所以我想打一个机架config.ru文件...

所以我有一个文件mpthmiws.rb其中包含

load 'ws_app.rb' 

MPTHMI.run 

并包含

load 'mpthmiws.rb' 

run MPTHMI.new 

当我运行

$ rackup config.ru 
>> Thin web server (v1.3.1 codename Triple Espresso) 
>> Maximum connections set to 1024 
>> Listening on 0.0.0.0:9292, CTRL+C to stop 

,去这里config.ru文件:

http://0.0.0.0:9292/battery/1.json 

但后来我得到了著名的“西纳特拉不知道这个小曲 - 试试'/battery/1.json'做“Hello World”结束

如果我从控制器/ BatteryController.rb文件中的第一条路线,并把它HMIMPT类中的ws_app.rb文件是这样的:

require 'rubygems' 
require 'sinatra' 
require 'sinatra/respond_to' 
require 'dm-core' 
require 'dm-migrations' 
require 'dm-timestamps' 
require 'json' 
require 'csv' 

load 'models/Battery.rb' 

Sinatra::Application.register Sinatra::RespondTo 
DataMapper::setup(:default,"sqlite3://#{Dir.pwd}/mpt_hmi.sqlite3") 

class MPTHMI < Sinatra::Base 

    get '/battery/:id' do 
    @battery = Battery.get(params[:id]) 
    respond_to do |wants| 
     wants.html { erb :battery } # html 
     wants.json { @battery.to_my_json.to_s } # json 
    end 
    end 

end 

我得到这个错误:

undefined method `respond_to' for #<MPTHMI:0x00000001240a80> 

我该如何解决这个问题? 谢谢

回答

1

首先,mpthmiws.rb和config.ru的东西过于复杂。删除mpthmiws.rb并使用此config.ru为使用rackup config.ru

require './ws_app' 

run MPTHMI 

如果你想与普通的旧ruby ws_app.rb运行应用程序时,使用此run.rb文件:

require './ws_app' 

MPTHMI.run! 

这使我们到下一点:永远不要使用load!它执行加载文件中的代码,但它不会带来任何已定义的变量,函数等。请改用require!在这里,您必须在路径前加上./或将./加到$LOAD_PATH,但是您可以省略.rb扩展名。

接下来是您的BatteryController.rb文件。它应该是这样的: 要求“西纳特拉/ respond_to代码”

class BatteryController < Sinatra::Base 
    register Sinatra::RespondTo 

    get '/battery/:id' do 
    # ... 
    end 

    get '/batteries' do 
    # ... 
    end 
end 

而且这也是地步,你register您的扩展 - 在你需要它的类。

现在我们知道如何load的作品,你可能已经注意到,你没有实际加载get块到MPTHMI类,而是在执行它们的类之外。这就是为什么你的应用程序无论如何与普通的旧ruby ws_app.rb

你可以正确包括您的控制器为一类use

# require all your gems 
# ... 

require './models/Battery' 
require './controller/BatteryController' 

DataMapper::setup(:default,"sqlite3://#{Dir.pwd}/mpt_hmi.sqlite3") 

class MPTHMI < Sinatra::Base 
    use BatteryController 
end 

您还可以在这里留下过的register。如果您还有其他问题,欢迎发表评论!


而这里的全DIFF:

diff --git a/config.ru b/config.ru 
index eaa15fe..1568544 100644 
--- a/config.ru 
+++ b/config.ru 
@@ -1,3 +1,3 @@ 
-load 'mpthmiws.rb' 
+require './ws_app' 

-run MPTHMI.new 
+run MPTHMI 
diff --git a/controller/BatteryController.rb b/controller/BatteryController.rb 
index 31e4910..c500c48 100644 
--- a/controller/BatteryController.rb 
+++ b/controller/BatteryController.rb 
@@ -1,20 +1,27 @@ 
-get '/battery/:id' do 
- @battery = Battery.get(params[:id]) 
- respond_to do |wants| 
-  wants.html { erb :battery } # html 
-  wants.json { @battery.to_my_json.to_s } # json 
- end 
-end 
+require 'sinatra/respond_to' 

-get '/batteries' do 
- @batteries = Battery.all 
- respond_to do |wants| 
- wants.html { erb :batteries } # html 
- wants.json { 
-  @batteries.all.inject({}) { |hsh, obj| 
-  hsh[obj.id] = obj.to_my_json 
-  hsh 
-  }.to_json 
- } 
+class BatteryController < Sinatra::Base 
+ register Sinatra::RespondTo 
+ 
+ get '/battery/:id' do 
+  @battery = Battery.get(params[:id]) 
+  respond_to do |wants| 
+  wants.html { erb :battery } # html 
+  wants.json { @battery.to_my_json.to_s } # json 
+  end 
    end 
-end 
+ 
+ get '/batteries' do 
+ @batteries = Battery.all 
+ respond_to do |wants| 
+  wants.html { erb :batteries } # html 
+  wants.json { 
+  @batteries.all.inject({}) { |hsh, obj| 
+   hsh[obj.id] = obj.to_my_json 
+   hsh 
+  }.to_json 
+  } 
+ end 
+ end 
+ 
+end 
\ No newline at end of file 
diff --git a/mpt_hmi.sqlite3 b/mpt_hmi.sqlite3 
index e69de29..9897cd9 100644 
Binary files a/mpt_hmi.sqlite3 and b/mpt_hmi.sqlite3 differ 
diff --git a/mpthmiws.rb b/mpthmiws.rb 
deleted file mode 100644 
index 87f3406..0000000 
--- a/mpthmiws.rb 
+++ /dev/null 
@@ -1,3 +0,0 @@ 
-load 'ws_app.rb' 
- 
-MPTHMI.run 
diff --git a/ws_app.rb b/ws_app.rb 
index 1cab867..4a6e332 100644 
--- a/ws_app.rb 
+++ b/ws_app.rb 
@@ -1,19 +1,18 @@ 
require 'rubygems' 
require 'sinatra' 
-require 'sinatra/respond_to' 
require 'dm-core' 
require 'dm-migrations' 
require 'dm-timestamps' 
require 'json' 
require 'csv' 

-load 'models/Battery.rb' 
+require './models/Battery' 
+require './controller/BatteryController' 

-Sinatra::Application.register Sinatra::RespondTo 
DataMapper::setup(:default,"sqlite3://#{Dir.pwd}/mpt_hmi.sqlite3") 

class MPTHMI < Sinatra::Base 
- 
- load 'controller/BatteryController.rb' 
+  
+ use BatteryController 

end 
+0

感谢padde,你的变化工作。 JSON视图仍然有效,但html视图不能。 Sinatra响应无法找到batteries.html.erb。我已经把这个文件放在一个名为views的目录中,在我做出更改之前它可以正常工作。有什么想法吗?谢谢 – Dimitri