我遇到了一个问题,无法弄清楚问题出在哪里。因为我相对较新,所以希望你能帮助我:)。
首先,我将帕德里诺与数据映射器宝石一起使用。
我有一个具有one_to_many关系的旅行和住宿模型
模型的外观:Trip.rb
class Trip
include DataMapper::Resource
# Associations
has n, :accommodations
property :id, Serial, :key => true
# many more properties
end
住宿.rb
class Accommodation
include DataMapper::Resource
has n, :appartments
belongs_to :trip, :child_key => [:trip_id]
# property <name>, <type>
property :id, Serial
end
根据 dm 文档,我假设关联是有效的
我想实现以下应用程序行为:
用户可以选择特定行程并添加或删除住宿
这是我的控制器看起来的样子:旅行.rb
HhtBackoffice.controllers :trips do
get :index do
@trips = Trip.all
render 'trips/index'
end
get :show, :with => :id do
@trip = Trip.get(params[:id])
set_current_trip(Trip.get(params[:id]))
render 'trips/show'
end
get :new do
@trip = Trip.new
render 'trips/new'
end
post :create do
@trip = Trip.new(params[:trip])
if @trip.save
flash[:notice] = 'Neue Reise wurde erfolgreich hinzugefügt'
redirect url(:trips, :edit, :id => @trip.id)
else
render 'trips/new'
end
end
..........
more code
........
end
住宿.rb
HhtBackoffice.controllers :accommodations do
get :index do
@accommodations = Accommodation.all
render 'accommodations/index'
end
get :new do
@trip = current_trip
@accommodation = @trip.accommodations.new # <-- This function is not known according to the error
render 'accommodations/new'
end
post :create do
@trip = current_trip
@accommodation = @trip.accommodations.new(params[:accommodation])
if @accommodation.save
flash[:notice] = 'Neue Reise wurde erfolgreich hinzugefügt'
redirect url(:accommodations, :edit, :id => @accommodation.id)
else
render 'accommodations/new'
end
end
.... more code here ....
end
如您所见,我使用了两个辅助函数。 set_current_trip(调用显示视图时)以跟踪当前行程。current_trip得到current_trip。
这是我的旅行/显示.haml视图
.block
.secondary-navigation
%ul.wat-cf
%li.first.active=link_to pat(:list), url(:trips, :index)
%li=link_to pat(:new), url(:trips, :new)
.content
%h2.title
.inner
-@trip.accommodations.each do |acco|
%ud
%li= acco.id
%li= acco.name
=button_to pat(:new), url(:accommodations, :new), :method => :get, :class => :button_to
.actions-bar.wat-cf
.actions=" "
这是住宿/新景观
.block
.secondary-navigation
%ul.wat-cf
%li.first=link_to pat(:list), url(:accommodations, :index)
%li.active=link_to pat(:new), url(:accommodations, :new)
.content
%h2.title
=pat(:new)
=mt(:accommodation)
.inner
-form_for :accommodation, url(:accommodations, :create), :class => :form do |f|
=partial "accommodations/form", :locals => { :f => f }
这是错误
#<NoMethodError: undefined method `accommodations' for nil:NilClass>
/home/paddy/Projects/hht_backoffice/app/controllers/accommodations.rb in block (2 levels) in <top (required)>
@trip.accommodations.new
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in call
proc { |a,p| unbound_method.bind(a).call }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in block in route
proc { |a,p| unbound_method.bind(a).call }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in []
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in block (3 levels) in process_destination_path
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in route_eval
throw :halt, yield
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in block (2 levels) in process_destination_path
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in catch
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in block in process_destination_path
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in instance_eval
Thread.current['padrino.instance'].instance_eval do
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in process_destination_path
Thread.current['padrino.instance'].instance_eval do
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/http_router-0.10.2/lib/http_router/node/root.rb in []
end
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/http_router-0.10.2/lib/http_router.rb in block in call
response = catch(:success) { @root[request] }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/http_router-0.10.2/lib/http_router.rb in catch
response = catch(:success) { @root[request] }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/http_router-0.10.2/lib/http_router.rb in call
response = catch(:success) { @root[request] }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in route!
if base.compiled_router and match = base.compiled_router.call(@request.env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/application/routing.rb in dispatch!
route!
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in block in call!
invoke { dispatch! }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in block in invoke
res = catch(:halt) { yield }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in catch
res = catch(:halt) { yield }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in invoke
res = catch(:halt) { yield }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in call!
invoke { dispatch! }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in call
dup.call!(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sass-3.2.5/lib/sass/plugin/rack.rb in call
@app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/rack-1.5.1/lib/rack/head.rb in call
status, headers, body = @app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/rack-1.5.1/lib/rack/methodoverride.rb in call
@app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/reloader.rb in call
@app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/logger.rb in call
status, header, body = @app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/showexceptions.rb in call
@app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/rack-1.5.1/lib/rack/session/abstract/id.rb in context
status, headers, body = app.call(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/rack-1.5.1/lib/rack/session/abstract/id.rb in call
context(env)
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in block in call
synchronize { prototype.call(env) }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in synchronize
yield
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/sinatra-1.3.4/lib/sinatra/base.rb in call
synchronize { prototype.call(env) }
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/router.rb in block in call
return app.call(
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/router.rb in each
@mapping.each do |host, path, match, app|
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/padrino-core-0.10.7/lib/padrino-core/router.rb in call
@mapping.each do |host, path, match, app|
/home/paddy/.rvm/gems/ruby-1.9.3-p374/gems/rack-1.5.1/lib/rack/handler/webrick.rb in service
status, headers, body = @app.call(env)
/home/paddy/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/webrick/httpserver.rb in service
si.service(req, res)
/home/paddy/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/webrick/httpserver.rb in run
server.service(req, res)
/home/paddy/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/webrick/server.rb in block in start_thread
通过帕德里诺控制台做"相同"没有问题:
irb(main):001:0> @trip = Trip.get(1)
DEBUG - (0.000101) SET sql_auto_is_null = 0
DEBUG - (0.000127) SET SESSION sql_mode = 'ANSI,NO_BACKSLASH_ESCAPES,NO_DIR_IN_CREATE,NO_ENGINE_SUBSTITUTION,NO_UNSIGNED_SUBTRACTION,TRADITIONAL'
DEBUG - (0.000092) SELECT `id`, `name`, `type`, `starts_at`, `ends_at`, `no_of_free_places`, `no_of_guests`, `raceday`, `created_at`, `updated_at` FROM `trips` WHERE `id` = 1 LIMIT 1
=> #<Trip @id=1 @name="Rofl" @type="Wettkampfreise" @starts_at=nil @ends_at=nil @no_of_free_places=nil @no_of_guests=nil @raceday=nil @created_at=#<DateTime: 2013-01-31T15:00:16+01:00 ((2456324j,50416s,0n),+3600s,2299161j)> @updated_at=#<DateTime: 2013-01-31T15:16:40+01:00 ((2456324j,51400s,0n),+3600s,2299161j)>>
irb(main):02:0> @trip.accommodations.new
=> #<Accommodation @id=nil @name=nil @no_of_appartments=nil @location=nil @capacity=nil @trip_id=1>
有什么提示可以解决这个问题吗?
好吧,我有一个猜测。我的current_trip对象为零。这些是我的帮助程序方法:
助手/旅行.rb
def set_current_trip(trip=nil)
@current_trip = trip
end
def current_trip
@current_trip
end
提前感谢!
编辑 2
这是我的路线。也许嵌套是让它工作的好方法我想打电话
=button_to pat(:new), url(:accommodations, :new), :method => :get, :class => :button_to
In My Trips/show.haml
但是我得到错误
route mapping for url(:accommodations_new) could not be found!
为什么?根据我的路线,我应该去/trips/:trip_id/住宿/新
路线
URL REQUEST PATH
(:accommodations, :index) GET /trips/:trip_id/accommodations
(:accommodations, :new) GET /trips/:trip_id/accommodations/new
(:accommodations, :create) POST /trips/:trip_id/accommodations/create
(:accommodations, :edit) GET /trips/:trip_id/accommodations/edit/:id
(:accommodations, :update) PUT /trips/:trip_id/accommodations/update/:id
(:accommodations, :destroy) DELETE /trips/:trip_id/accommodations/destroy/:id
(:base, :index) GET /
(:trips, :index) GET /trips
(:trips, :show) GET /trips/show/:id
(:trips, :new) GET /trips/new
(:trips, :create) POST /trips/create
(:trips, :edit) GET /trips/edit/:id
(:trips, :update) PUT /trips/update/:id
(:trips, :destroy) DELETE /trips/destroy/:id
current_trip
返回 nil。首先,当您调用其方法之一时,请确保@trip不是 nil,因为如果尚未设置行程怎么办?
get :new do
@trip = current_trip
if @trip
@accommodation = @trip.accommodations.new
render 'accommodations/new'
else
# trip is nil. Call an error or something.
end
end
其次,我不确定您的帮助程序方法是否会返回行程,因为@current_trip尚未初始化。current_trip有什么用?是否要跨会话为用户保留它?如果是这样,您可能需要将current_trip保存在 Cookie 中。
def set_current_trip(trip_id = 0)
response.set_cookie 'current_trip', :value => trip_id, :path => '/', :expires => Time.now + 60 * 60 * 24 * 365 * 20
end
def current_trip
trip_id = request.cookies["current_trip"]
current_trip = Trip.get trip_id
end