Split string into 160-character chunks while adding text to each part
Some notes:


Is your code inside a module or a class, I guess? You can include it in the question.
As a general rule, favour the user of affirmative statements (if instead of unless).
If you spend enough time with a pencil and a paper, maybe you'd get to a nice formula get_total_parts(message_size, sms_size, parts_message_min_size), but it's not trivial, that's for sure. A pre-computing of the max_size (along with some extra info you'll need) is a bit tedious to write but fast. For example, what's the maximum size if you have a total count with exactly 3 digits (100-999)? (SMS_SIZE - PARTS_MSG_MIN_SIZE - 2) * 9 + (SMS_SIZE - PARTS_MSG_MIN_SIZE - 3) * 90 + (SMS_SIZE - PARTS_MSG_MIN_SIZE - 4) * 900. You get the idea.


I'd write:

module SMS
  SMS_LENGTH = 160

  PARTS_MESSAGE = " - Part %{n} of %{total}"

  SPLIT_INFO = (1..70).map do |ndigits|
    base_size = (PARTS_MESSAGE % {n: "1", total: "1"}).size 
    parts_per_digit = (0...ndigits).map do |n|
      (SMS_LENGTH - base_size - (ndigits + n - 1)) * (9 * (10 ** n))
    end
    {
      max_size: parts_per_digit.reduce(0, :+), 
      size_of_first_parts: parts_per_digit[0...-1].reduce(0, :+),
      min_parts: 10**(ndigits - 1) - 1, 
      msgsize_for_last_parts: (SMS_LENGTH - base_size - 2 * (ndigits - 1))
    }
  end

  def self.get_total_parts_for_long_message(text)
    info = SPLIT_INFO.detect { |h| text.size &lt;= h[:max_size] } or 
      raise ValueError("Message text too large")
    info[:size_of_first_parts] + 
      Rational(text.size - info[:min_size], info[:msgsize_for_last_parts]).ceil
  end 

  def self.send_sms_message(text, to, from)
    if text.length &lt;= SMS_LENGTH
      deliver_message_via_carrier(text, to, from)
    else
      total_parts = get_total_parts_for_long_message(text) 
      idx = 0

      (1..total_parts).each do |part_index|
        split_message = PARTS_MESSAGE % {n: part_index, total: total_parts}
        user_message_size = SMS_LENGTH - split_message.size
        message_text = text[idx, SMS_LENGTH - user_message_size]
        deliver_message_via_carrier(message_text + split_message, to, from)
        idx += user_message_size
      end
    end
  end

  def self.deliver_message_via_carrier(text, to, from)
    puts("Sending #{from} -&gt; #{to}: #{text} - #{text.size} bytes")
  end
end