Как отсортировать некоторые значения из массива в контроллере в Rails? - PullRequest
0 голосов
/ 11 марта 2010

У меня есть массив ссылок, который я сохраняю в базе данных. Проблема в том, что записи не сохраняются в порядке массива, т.е. ссылки [1] сохраняются перед ссылками [2] и т. Д. ...

Это пример из файла представления:

<p>
  <label for="links_9_label">Label</label>
  <input id="links_9_name" name="links[9][name]" size="30" type="text" />
  <input id="links_9_url" name="links[9][url]" size="30" type="text" />
</p>

А это мой контроллер:

def create
    @links = params[:links].values.collect { |link| @user.links.new(link) }

    respond_to do |format|
         if @links.all?(&:valid?)
         @links.each(&:save!)

        flash[:notice] = 'Links were successfully created.'
        format.html { redirect_to(links_url) }
      else
        format.html { render :action => "new" }
      end
    end
  end

Заранее спасибо!

Alfred

Ответы [ 2 ]

1 голос
/ 11 марта 2010

Причина, по которой ваши ссылки хранятся не по порядку, заключается в том, что вы не представляете их в БД по порядку.

- Объект param не является массивом, хотя в некоторой степени он может выглядеть как один. Скорее, это хеш, где ключи являются целыми числами. Вы можете сказать, что это правда, потому что вам нужно использовать

params[:links].values.collect

если бы это был массив, вы бы использовали

params[:links].collect

Каждый раз, когда вы используете метод .values, порядок ключей не определен.

Решение

Я согласен с @ p.g, что вы должны быть очень осторожны при использовании идентификаторов db в качестве заказа. Например, предположим, вы хотите изменить порядок позже? У меня часто в списке есть поле list_order.

Чтобы изменить порядок параметров и сохранить в порядке расположения клавиш, попробуйте следующее:

links_param = params[:links]
ordered_keys = links_param.keys.sort
@links = ordered_keys.collect {|key| @user.links.new(links_param[key])}

Добавлено: также обратите внимание, что ключи могут входить в виде строк, а не целых чисел. Так что, если у вас их более 10, может быть идея отсортировать их как целые числа:

ordered_keys = links_param.keys.sort{|a,b| a.to_i <=> b.to_i}
<ч />

Добавлено в ответ на комментарий о сохранении "display_order" -

Сначала добавьте новое поле в модель: display_order. Обязательно добавьте индекс в поле, так как вы будете сортировать его.

Затем в вашем контроллере вам нужно выставить ключ к модели. Например, что-то вроде этого:

 links_param = params[:links]
 links_params.keys.each{|key|links_params[key][:display_order] = key.to_i}

Теперь, когда вы создаете свой объект user.link, параметр display_order также будет установлен.

0 голосов
/ 11 марта 2010

Измените вашу схему так, чтобы она имела столбец display_order или что-то подобное, и выдавайте это как скрытый ввод на переднем конце.

Не рекомендуется полагаться на столбец id для упорядочения, так как это, по сути, произвольное значение, создаваемое БД, которое следует логической последовательности в большинстве времени. Наличие отдельного столбца для заказа не нарушит DRYness, потому что это (технически) для другой цели.

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