attr_accessor для даты и проблемы с использованием select_date

Я пытаюсь использовать attr_accessor для даты, которая обычно работает нормально, за исключением случаев, когда я пытаюсь использовать ее с вспомогательным методом select_date.

Глядя на код вспомогательного метода, я предполагаю, что он ищет столбец таблицы с типом даты. И в этом случае, поскольку таблицы нет, она обрабатывается неправильно, и я получаю:

ActiveRecord::MultiparameterAssignmentErrors

"search"=>{"number_of_days"=>"3",
 "searchable_id"=>"6933",
 "startdate(1i)"=>"2011",
 "startdate(2i)"=>"2",
 "startdate(3i)"=>"11"}}

Есть ли способ обойти это? Или мне нужно создать какой-то перед фильтром в контроллере? Я бы предпочел сделать это на уровне модели, но я не уверен, как поступить в этом случае? Attr_accessor для каждого кажется слишком убийственным. У кого-нибудь есть элегантное решение?


person holden    schedule 11.02.2011    source источник
comment
Я хотел бы сделать что-то вроде этого: stackoverflow. com/questions/93277/, но у меня это не сработало на Rails3   -  person holden    schedule 11.02.2011


Ответы (4)


Поля attr_accessor обычно не сохраняются при сохранении/обновлении модели. Как вы обновляете модель?

Кроме того, вы можете преобразовать параметры startdate в объект даты следующим образом:

@start_date = Date.civil(params[:search][:"startdate(1i)"].to_i,params[:search][:"startdate(2i)"].to_i,params[:search][:"startdate(3i)"].to_i)

Проверьте здесь

person Phyo Wai Win    schedule 11.02.2011
comment
Я использую ActiveModel для обработки нескольких вещей без бэкэнда БД. Большая часть материала входит в сеанс, модель обрабатывает проверку данных, поэтому я бы хотел, чтобы это было и там. - person holden; 11.02.2011

С опозданием, но на случай, если кто-то еще споткнется, ответ для современных рельсов лежит в include ActiveRecord::AttributeAssignment в вашей модели.

Этот ответ сделал это за меня.

person cluesque    schedule 12.03.2021

select_date предназначен для создания раскрывающихся списков, которые не связаны с полем модели (с идеей, что вы можете затем подобрать их с другой стороны и делать с ними все, что хотите). Я предполагаю, что вы имеете в виду date_select, который не соответствует модели?

В любом случае, насколько я знаю, короче говоря, нет хорошего и красивого способа заставить это работать. Это не из-за того, как работает помощник, а из-за того, как активная запись обрабатывает эти атрибуты, разделенные на несколько параметров.

Немного подробнее, если вам интересно, причина, по которой это не работает легко, заключается в том, что когда Active Record имеет дело с параметрами, которые вы передали, они проходят через execute_callstack_for_multiparameter_attributes, который интерпретирует ключи, разделенные на стиль "date(1i)" , и помещает их в применимый класс, которым они должны быть (объект даты или времени). Способ определения того, должен ли он создавать дату или время, заключается в проверке его по типу атрибута (см. здесь), но поскольку атрибут startdate не привязан к определенному типу, он не обрабатывается как столбец даты или даты и времени. в БД бы.

Я думаю, что я бы поступил с этим так же, как с @Phyo-Wai-Win, но использовал бы select_date для установки другого параметра за пределами пространства имен «поиск», которое вы затем передаете в модель соответствующим образом в контроллере. Таким образом, это не так много работы, и это означает, что вы не возитесь с тем, как вы инициализируете запись или какие атрибуты она ожидает.

person idlefingers    schedule 11.02.2011

Я немного опоздал, но я только что столкнулся с этой проблемой, и мне не понравился верхний ответ. Я нашел в исходниках ActiveRecord метод под названием extract_callstack_for_multiparameter_attributes (он отличается от упомянутого метода idlefingers)

У меня есть следующий метод в моей модели. Я вызываю этот метод вручную, но вы, вероятно, могли бы переопределить update_attributes, чтобы он запускался автоматически при сохранении из контроллера. Аргумент params на самом деле является params[:my_model] из контроллера.

attr_accessor :submit_from, :submit_to

def set_dates(params)
  dates = extract_callstack_for_multiparameter_attributes(params)

  dates.each_pair do |field, date_array|
    send "#{field}=", Date.new(*date_array)
  end
end
person Peter Brown    schedule 04.06.2011