views:

651

answers:

1

Hi,

I'm pulling my hair out trying to build a little random photo JSON feed using DataMapper/Sinatra. Here's what I have so far..

Photo.favorites.to_json(:methods => [:foo, :bar])

So that works fine. The to_json method is provided in the dm-serializer library. All I want to do is randomize that feed so the photos don't show up in the same order every time. Since DataMapper doesn't have built-in support for random selects, I tried sorting the results, but to_json gets mad because the sort_by turns the DataMapper::Collection into an Array..

Photo.favorites.sort_by{rand}.to_json(:methods => [:foo, :bar])
# wrong argument type Hash (expected Data)

I searched for that error and saw a lot of Rails-related stuff about ActiveRecord and conflicts between competing to_json methods, but nothing really about DataMapper. A lot of people recommended using json_pure instead of the json gem, so I gave that a try by adding require 'json/pure' to my Sinatra app. Now the query above gives me this error instead..

Photo.favorites.sort_by{rand}.to_json(:methods => [:foo, :bar])
# undefined method `[]' for #<JSON::Pure::Generator::State:0x106499880>

I also tried doing the randomization with straight SQL:

def self.random
  repository(:default).adapter.query('SELECT * FROM photos WHERE favorite = 1 ORDER BY RAND();')
end

But that doesn't really work for me because it returns Struct objects with attributes, rather than instances of the actual Photo class. This means I can't leverage the handy to_json arguments like :methods.

Lastly I tried using find_by_sql, but I guess the method's been removed from DataMapper?

def self.random
  find_by_sql("SELECT * FROM `photos` ORDER BY RAND();")
end
# undefined method `find_by_sql' for Photo:Class

Sheesh! Any thoughts on how to resolve this?

+2  A: 

The find_by_sql method was moved to the dm-ar-finders plugin.

dkubb
Thanks for the tip, dkubb. Installing the dm-ar-finders gem gave me access to the find_by_sql method, but things still aren't quite right: I can now call Photos.random, but I cannot mix named scopes with find_by_sql queries, so I can't do Photos.random.favorites. That's fine though; I just put all the criteria right into the SQL statement itself, BUT.. the to_json method only works if I don't pass :method arguments. When I do, I get a JSON feed for all the Photos in the database. Hmm..
Zeke