Выбор Набора Ruby on Rails - как предварительно выбрать правильное значение?

Более информативный вопрос заключается в том, что делает код не потокобезопасным, и ответ заключается в том, что существует четыре условия, которые должны быть выполнены ... Представьте себе следующий код (и его перевод на машинный язык)

totalRequests = totalRequests + 1
MOV EAX, [totalRequests]   // load memory for tot Requests into register
INC EAX                    // update register
MOV [totalRequests], EAX   // store updated value back to memory
  1. Первое условие - наличие областей памяти, доступных из нескольких потоков. Как правило, эти местоположения являются глобальными / статическими переменными или могут быть доступны из кучи в глобальных / статических переменных. Каждый поток получает свой собственный кадр стека для локальных переменных в области функций / методов, поэтому эти локальные переменные функции / метода otoh (которые находятся в стеке) доступны только из одного потока, которому принадлежит этот стек.
  2. Вторым условием является то, что существует свойство (часто называемое инвариантом ), которое связано с этими общими ячейками памяти, которые должны быть истинными или действительными, чтобы программа функционировала правильно. В приведенном выше примере свойство заключается в том, что « totalRequests должно точно представлять общее количество раз, когда какой-либо поток выполнял какую-либо часть инструкции приращения ». Как правило, это свойство инварианта должно содержать значение true (в этом случае totalRequests должно содержать точное число), прежде чем произойдет обновление, чтобы обновление было корректным.
  3. Третье условие заключается в том, что свойство инварианта НЕ выполняется во время какой-либо части фактического обновления. (Это временно недействительно или ложно во время некоторой части обработки). В этом конкретном случае, с момента получения totalRequests до момента сохранения обновленного значения, totalRequests не не не удовлетворяет инварианту.
  4. Четвертое и последнее условие, которое должно произойти для гонки (и, следовательно, для кода НЕ быть «поточно-ориентированным»), заключается в том, что другой поток должен быть в состоянии чтобы получить доступ к общей памяти , а инвариант нарушается, вызывая, таким образом, непоследовательное или неправильное поведение.
7
задан Michael Schmitz 30 June 2009 в 19:46
поделиться

2 ответа

collection_select не поддерживает выбранную опцию, в на самом деле это не нужно. Он автоматически выбирает параметр, значение которого совпадает со значением объекта конструктора форм.

Позвольте мне показать вам пример. Предполагая, что каждое сообщение принадлежит определенной категории.

@post = Post.new

<% form_for @post do |f| %>
  <!-- no option selected -->
  <%= f.collection_select :category_id, Category.all, :id, :name, :prompt => true  %>
<% end %>

@post = Post.new(:category_id => 5)

<% form_for @post do |f| %>
  <!-- option with id == 5 is selected -->
  <%= f.collection_select :category_id, Category.all, :id, :name, :prompt => true  %>
<% end %>

РЕДАКТИРОВАТЬ :

Я бы предложил использовать репрезентативные имена переменных. Используйте @categories вместо @category. :) Кроме того, отделите логику обновления от представления только для чтения.

def categories #Step 2
  @listing = Listing.find(params[:listing_id])
  @seller = Seller.find(@listing.seller_id)
  @categories = Category.find(:all)
  @listing.complete = "step1"

  respond_to do |format|
    if @listing.update_attributes(params[:listing])
      flash[:notice] = 'Step one succesful. Item saved.'
      format.html #categories.html.erb
    end
  end
end

<% form_for @listing do |f| %>
  <%= f.collection_select :category_id, @categories, :id, :name, :prompt => true %>
<% end %>

Если он не работает (то есть выбирает подсказку), это означает, что либо у вас нет category_id, связанной с этой записью, либо коллекция Category пуста. Убедитесь, что вы не сбрасываете значение category_id для @listing где-нибудь до того, как объект будет передан в форму.

РЕДАКТИРОВАТЬ 2:

class Category
  def id_as_string
    id.to_s
  end
end

<%= f.collection_select :category_id, Category.all, :id_as_string, :name, :prompt => true  %>
12
ответ дан 6 December 2019 в 19:41
поделиться

Мой category_id сохраняется в базе данных как строка, но сравнение выполняется между целыми значениями.

if @listing.category_id != "" 
@listing.category_id = @listing.category_id.to_i
end

Это решает проблему - теперь предварительно выбрано правильное значение.

1
ответ дан 6 December 2019 в 19:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: