2012-06-28 4 views
1

J'ai un fichier d'application qui ressemble à ceci ws_app.rb:Sinatra + rack de routage

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 

Les modules/Battery.rb ressemble à ceci:

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 

Le contrôleur/BatteryController.rb fichier ressemble à ceci:

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 

cela fonctionne parfaitement quand je lance Sinatra normalement, comme ceci:

$ 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 

Ensuite, allez ici:

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

je reçois le JSON Je me attends:

{: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} 

mais je dois déployer cela sur un serveur web Cherokee, donc je veux faire un fichier config.ru rack pour cette ...

J'ai donc un mpthmiws.rb de fichier qui contient

load 'ws_app.rb' 

MPTHMI.run 

Et un fichier qui contient config.ru

load 'mpthmiws.rb' 

run MPTHMI.new 

Quand je lance

$ 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 

et aller ici:

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

mais je reçois le célèbre « Sinatra ne sait pas ce que ça donne - essayez '/battery/1.json' faites "Hello World" fin

Si je prends la première route du contrôleur/fichier BatteryController.rb et le mettre à l'intérieur de la classe HMIMPT dans le fichier ws_app.rb comme ceci:

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 

Je reçois cette erreur:

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

Comment puis-je résoudre ce problème? Merci

Répondre

1

Tout d'abord, cette chose avec mpthmiws.rb et config.ru est trop compliquée. Supprimer mpthmiws.rb et utiliser cette config.ru pour une utilisation avec rackup config.ru:

require './ws_app' 

run MPTHMI 

Si vous voulez exécuter l'application avec le vieux ruby ws_app.rb ordinaire, utilisez ce fichier run.rb:

require './ws_app' 

MPTHMI.run! 

qui apporte nous au point suivant: N'UTILISEZ JAMAIS load! Il exécute le code dans le fichier chargé, mais il n'apporte aucune variable définie, aucune fonction, etc. Utilisez require à la place! Ici vous devez préfixer le chemin avec ./ ou ajouter ./ à $LOAD_PATH, mais à son tour, vous pouvez omettre l'extension .rb.

Ensuite, il y a le fichier BatteryController.rb. Il devrait ressembler à ceci: require « sinatra/respond_to »

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

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

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

Et cela est aussi le point où vous register vos extensions - dans la classe où vous en avez besoin.

Maintenant que nous comprenons comment load fonctionne, vous avez déjà remarqué que vous ne chargez pas réellement les get blocs dans la classe MPTHMI, mais plutôt de les exécuter en dehors de la classe. C'est la seule raison pour laquelle votre application fonctionnait quand même avec ruby ws_app.rb!

Vous pouvez bien inclure votre contrôleur dans une classe avec 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 

Vous pouvez également laisser tomber le register ici. N'hésitez pas à commenter si vous avez d'autres questions!


Et voici la pleine 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

Merci padde, vous les changements de travail. Les vues JSON fonctionnent toujours, mais pas les vues html. Sinatra répond avec ne peut pas trouver batteries.html.erb. J'ai placé ce fichier dans un répertoire appelé vues qui a bien fonctionné avant que je fasse les changements. Des pensées? Merci – Dimitri

Questions connexes