Ordem dos parâmetros em Foo.new(params[:foo]), precisa de um antes do outro (Rails)
-
23-09-2019 - |
Pergunta
Estou com um problema que não sei como resolver.Tem a ver com o hash de parâmetros não classificados.
Eu tenho um objeto Reserva que possui um atributo virtual time= e um atributo virtual eating_session= quando defino o time= também quero validá-lo por meio de uma solicitação de servidor externo.Faço isso com a ajuda do método times() que faz uma busca em outro servidor e salva todos os horários possíveis na variável @times.
O problema agora é que o método times() precisa do atributo eating_session para descobrir quais horários são válidos, mas o rails às vezes chama o método times= primeiro, antes de haver qualquer eating_session no objeto Reserva quando eu apenas faço @reservation = Reservation. novo(params[:reserva])
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
Não tenho ideia de como consertar isso, qualquer ajuda é apreciada.
Solução
O que costumo fazer neste caso é enviar o código dependente para uma validação:
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