3

I have the following method which creates and then executes an SQL query:

def edition_authors(edition, authors)
  query_string = "contributor_type = ? AND author = ?"
  for i in 1..authors.length - 1
    query_string += " OR author = ?"
  end
  return edition.contributors.where(query_string, 'Author', authors)
end

The last line is the one I'm having trouble with. I want the 'authors' array to somehow turn into a set of strings. For instance, if the authors array contained ['James Joyce', 'Cory Doctorow', 'Cormac McCarthy'], I'd like that last line to read like:

return edition.contributors.where(query_string, 'Author', 'James Joyce', 'Cory Doctorow', 'Cormac McCarthy')

How could I accomplish this?

2 Answers 2

6

Depends which rails and which ruby you are using,

  1. ActiveRecord already has this functionality in Rails 3: Model.where(:my_field => ['Author', 'James Joyce', 'Cory Doctorow', 'Cormac McCarthy'])

  2. arr.map{|v| v.to_s.inspect} will get you a comma separated list

  3. arr.join(',') will give you a comma separated list, no quotes.

Then you can use this string however you wish.

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

Comments

2

Try this:

  1. Instead of using a big bunch of ORs, use a SQL IN clause, and
  2. then use Array#join to supply the values

So:

.where("contributor_type = ? AND author IN (?)", 'Author', authors.join("','")) 

should do the trick, with some caveats: string values in a SQL IN clause need to be single quoted and comma separated SELECT * FROM fubar WHERE blah IN ('foo','bar','baz'); I think Rails is clever about knowing how to quote things, so look in the Rails log to see what SQL is being generated if you're getting an error.

Also, since your values may contain single quotes (Georgia O'Keefe) I am not sure if Rails is smart enough to escape these for you when used in this manner.

Bonus tip: make sure there's an index on the Author column. This is an expensive query, in general.

3 Comments

Aw snap! @Michael's answer is much better than mine. Rails is so cool, of course there's a simple way :-).
your join is missing the beginning and end single quotes, you would need to add them in.
Actually, that was "hopefully intentional" which is what I was implying by "Rails is clever..." -- you don't need to quote strings when used in a placeholder. But yeah, if I am wrong, the IN clause would be ...IN ('?')... or maybe the value would need to be something horrific like "'#{authors.join("','")}'", which leads me to my comment, that your answer is better all around :-)

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.