Как я могу ссылаться на атрибуты перед сохранением? - PullRequest
1 голос
/ 17 ноября 2010

У меня есть модель резервирования, которая принимает атрибут встречи как date и имеет виртуальный атрибут duration, который указывает, сколько времени займет встреча. Реальный атрибут booking_end занимает время, на которое ссылается все мое приложение. Однако для удобства ввода мы используем продолжительность вместо выбора другого Time. Поля ниже:

def duration
  ( (booking_end - date) / 1.hour ).round( 2 ) rescue nil
end

def duration=(temp)
  if ( true if Float(temp) rescue false )
    self.booking_end = time_round(date + temp.to_f.hours, 15.minutes)
  else  
    errors.add(:duration, "must be a number, stated in hours.")
    self.booking_end = nil
  end
end

Все заканчивается неудачей, когда я ссылаюсь на поле date при создании новой записи. Я получаю ошибку «ноль», потому что дата не была инициализирована. Как я могу решить эту проблему? Остальное работает при обновлении существующих записей.

Ответы [ 2 ]

0 голосов
/ 17 ноября 2010

Я попытался инициализировать модель с помощью

Reservation.new(params[:reservation][:date]) 

и затем вызвать update_attributes.Это работает в консоли, но не иначе.Единственный обходной путь, который, кажется, имеет место - это удалить длительность из хеша params и затем передать его обратно перед сохранением.Это кажется действительно глупым, и, вероятно, не правильным подходом для Rails.Использование 4 строк, где должно хватить.

duration = params[:reservation][:duration]
params[:reservation].delete('duration')
@reservation = Reservation.new(params[:reservation])
@reservation.duration = duration
# Then go to save, etc.

Есть ли другой способ инициализации модели или, возможно, доступа к хешу атрибутов изнутри модели?

0 голосов
/ 17 ноября 2010

Когда вы вызываете Reservation.new (: date => date,: duration => duration) ActiveRecord :: Base назначает значения атрибутов таким образом (см. Метод assign_attributes):

attributes.each do |k, v|
  ...
  respond_to?("#{k}=") ? send("#{k}="", v) 
  ...

Hash # каждый метод выполняет итерацию значений таким образом, что ключ : duration доступен до : дата один, поэтому дата равен нулю в методе duration = :

ruby-1.8.7-p302 > {:date => Date.today, :duration => 5}.each do |key,value|
ruby-1.8.7-p302 >     puts "#{key} = #{value}"
ruby-1.8.7-p302 ?>  end
duration = 5
date = 2010-11-17

Так что вам нужно будет позвонить duration = после инициализации.

Или вы можете переопределить Reservation # initialize для вызова super с: date, а затем update_attributes с остальными параметрами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...