Цикл While для создания нескольких записей в rails

#ruby-on-rails #ruby #ruby-on-rails-3

#ruby-on-rails #ruby #ruby-on-rails-3

Вопрос:

Я создаю приложение, в котором пользователи могут приобретать номера отслеживания. У меня есть модель заказа и модель транзакции заказа. Если транзакция заказа возвращается от шлюза с успехом, я использую обратный вызов after_save для запуска метода, который создает номера отслеживания и вставляет их в базу данных. Иногда пользователь просто заказывает одну, но если они заказывают более одной, я, похоже, не могу заставить rails создавать и вставлять более одной записи.

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

 def create_trackables
      if self.success == true
        @order = Order.find(order_id)
        @start = 0
        while @start < @order.total_tokens
          @trackable_token = Tracker.create_trackable_token
          @start  = 1
          @trackable ||= Tracker.new(
            :user_id => @current_user,
            :token => @trackable_token,
            :order_id => order_id
            )
        @trackable.save 
        end
      end
    end
  

Ответ №1:

dmarkow прав, что вы должны использовать trackable вместо @trackable , но вы также должны использовать = вместо ||= . Вы также могли бы просто использовать create . Вот как я бы это написал:

  def create_trackables
    return unless self.success
    order = Order.find(order_id) #you shouldn't need this line if it has_one :order
    1.upto(order.total_tokens) do
      Tracker.create!(
                     :user_id => @current_user,
                     :token => Tracker.create_trackable_token,
                     :order_id => order_id
                     )
    end
  end
  

Комментарии:

1. Исправьте — я полностью пропустил это.

2. Это немного запоздало, но я недавно обнаружил волшебный трюк, позволяющий ускорить создание. Сделайте вот так: «определить create_trackables…. Отслеживание. транзакция выполняется … * code*… Tracker.create(что-то)… end

3. @Cort3z — если вы хотите сделать это быстро, используйте activerecord-import

Ответ №2:

Измените @trackable на trackable , чтобы сохранить область действия цикла. В противном случае, при втором запуске цикла значение @trackable уже имеет значение, поэтому вызов Tracker.new не выполняется, и @trackable.save строка просто продолжает повторно сохранять ту же запись. (Редактировать: также удалите ||= и просто используйте = ).

 def create_trackables
  if self.success == true
    @order = Order.find(order_id)
    @start = 0
    while @start < @order.total_tokens
      @trackable_token = Tracker.create_trackable_token
      @start  = 1
      trackable = Tracker.new(
        :user_id => @current_user,
        :token => @trackable_token,
        :order_id => order_id
        )
      trackable.save 
    end
  end
end
  

Комментарии:

1. Кажется, что все еще сохраняется только одна строка… Я даже изменил верхнюю переменную в операторе while на число для проверки, и я получаю из этого только одну строку. Может @start быть проблема?