3

I'm building an application where users can purchase tracking numbers. I have an Order model and an Order Transaction model. If the Order Transaction returns from the gateway with success, I'm using an after_save callback to trigger a method that creates the tracking numbers and inserts them into the database. Sometimes a user just orders one, but if they order more than one, I can't seem to get rails to create and insert more than one record.

Here's what I'm using -- I've never had to user a loop like this, so I'm not sure what I'm doing wrong.

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

2 Answers 2

6

dmarkow is right that you should use trackable instead of @trackable but you also should be using = instead of ||=. You also might as well just use create. Here's how I'd write it:

 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

Sign up to request clarification or add additional context in comments.

3 Comments

Correct -- I completely missed that.
This is a bit late, but I newly discovered a magic tric to make creation fast. Do like this: "def create_trackables.... Tracker.transaction do ...*code*... Tracker.create(something)... end
@Cort3z - if you want to do it fast, use activerecord-import
2

Change @trackable to trackable to keep it scoped to the loop. Otherwise, the second time the loop runs, @trackable already has a value so the call to Tracker.new doesn't execute, and the @trackable.save line just keeps re-saving the same record. (Edit: Also remove the ||= and just use =).

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 Comment

It still seems to be saving only the one row ... I even changed the upper variable in the while statement to a number to test and I'm just getting one row out of it. Could @start be the problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.