Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamonduty/930211 to your computer and use it in GitHub Desktop.
Save adamonduty/930211 to your computer and use it in GitHub Desktop.
# The problem: In your Rails 3 project, you have a model Request that models a
# user's request for content related to a specific problem or topic. The user
# can tag her request with any number of words. These are modeled by a Tag class
# backed by a tags DB table. Since you want unique records per tag, you have a
# Tagging class backed by a taggings table. Taggings is a a many-to-many table
# with some additional information. Also, other models in the application
# besides requests can be tagged: The Tagging class defines a polymorphic
# relationship "taggable" with those models.
#
# So pretty soon you want to look up all the requests that are tagged with
# certain words, say "bunnies" and "bacon".
#
# You can do that with raw SQL:
Request.find_by_sql("
SELECT * FROM requests
INNER JOIN taggings ON taggings.taggable_id = requests.id AND taggings.taggable_type = 'Request'
INNER JOIN tags ON taggings.tag_id = tags.id
WHERE tags.contents = 'bunnies' OR tags.contents = 'bacon'
")
# But you are using Rails 3. You have Arel. So how do you do the chained inner
# joins from requests to taggings and then taggings to tags?
# With Arel
Request.joins({ :taggings => :tags }).where('taggings.taggable_type' = 'Request')
.where('tags.contents' => ["bunnies", "bacon"])
# You probably do not want duplicate Request records
Request.joins({ :taggings => :tags }).where('taggings.taggable_type' = 'Request')
.where('tags.contents' => ["bunnies", "bacon"]).select("DISTINCT requests.*")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment