0

I would like to create an Active Record object with a string attribute containing string interpolation.

My Schema for the model looks like this:

  create_table "twilio_messages", force: true do |t|
    t.string   "name"
    t.string   "body"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

And I have created an object of this model using Active Admin that looks as the following:

  => #<TwilioMessage id: 5, name: "weekly_message", body: "\#{user.firstname} you're on the list for this week'...", created_at: "2014-05-29 22:24:36", updated_at: "2014-05-30 17:14:56"> 

The issue is that the string I am creating for the body should look like this:

"#{user.firstname} you're on the list for this week's events! www.rsvip.biz/#events"

So that the user.firstname gets interpolated into the string and therefore prints out the user's name.

How do I create this type of record without the database automatically trying to escape the interpolation with a "\" ?

1 Answer 1

3

You can do it like that unless you want to use nasty things like eval. String interpolation only takes place in string literals, you can't say s = '#{x}' (not the single quotes) and then replace x later when you want to use s.

There is String#% though:

str % arg → new_str

Format—Uses str as a format specification, and returns the result of applying it to arg. If the format specification contains more than one substitution, then arg must be an Array or Hash containing the values to be substituted. See Kernel::sprintf for details of the format string.

So you could use a body like this:

m = TwilioMessage.create(
  :body => "%{firstname} you're on the list for this week's events! www.rsvip.biz/#events",
  ...
)

and then later, when you have your user, fill in the message like this:

body = m.body % { :firstname => user.firstname }

Of course, you'd have to know that %{firstname} was in the string. If you only have a small number of things that you want to interpolate, then you could supply them all and let % pick out the ones that are needed:

body = m.body % {
  :firstname => user.firstname,
  :lastname  => user.lastname,
  :email     => user.email
}

or even add a method to your users:

def msg_vals
  {
    :firstname => self.firstname,
    :lastname  => self.lastname,
    :email     => self.email
  }
end

and then say things like:

body = m.body % user.msg_vals
Sign up to request clarification or add additional context in comments.

1 Comment

@Kirti Thanks for the nested quote fix.

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.