I have a problem which I don't know how to fix. It has to do with the unsorted params hash.
I have a object Reservation which has a virtual time= attribute and a virtual eating_sessi开发者_JS百科on= attribute when I set the time= I also want to validate it via an external server request. I do that with help of the method times() which makes a lookup on a other server and saves all possible times in the @times variable.
The problem now is that the method times() needs the eating_session attribute to find out which times are valid, but rails sometimes calls the times= method first, before there is any eating_session in the Reservation object when I just do @reservation = Reservation.new(params[:reservation])
class ReservationsController < ApplicationController
def new
@reservation = Reservation.new(params[:reservation])
# ...
end
end
class Reservation < ActiveRecord::Base
include SoapClient
attr_accessor :date, :time
belongs_to :eating_session
def time=(time)
@time = times.find { |t| t[:time] == time }
end
def times
return @times if defined? @times
@times = []
response = call_soap :search_availability {
# eating_session is sometimes nil
:session_id => eating_session.code, # <- HERE IS THE PROBLEM
:dining_date => date
}
response[:result].each do |result|
@times << {
:time => "#{DateTime.parse(result[:time]).strftime("%H:%M")}",
:correlation_data => result[:correlation_data]
}
end
@times
end
end
I have no idea how to fix this, any help is apriciated.
What I often do in this case is push the dependent code into a validation:
class ReservationsController < ApplicationController
def new
@reservation = Reservation.new(params[:reservation])
# ...
end
end
class Reservation < ActiveRecord::Base
include SoapClient
attr_accessor :date, :time
belongs_to :eating_session
validate :validate_time
def validate_time
errors.add_to_base "Time is invalid" unless @time = times.find { |t| t[:time] == time }
end
def times
return @times if defined? @times
@times = []
response = call_soap :search_availability {
# eating_session is sometimes nil
:session_id => eating_session.code, # <- HERE IS THE PROBLEM
:dining_date => date
}
response[:result].each do |result|
@times << {
:time => "#{DateTime.parse(result[:time]).strftime("%H:%M")}",
:correlation_data => result[:correlation_data]
}
end
@times
end
end
精彩评论