title: Polymorphic Relationship Table Queries in Rails — find object by multiple
body: <p>I have a relationship table in a rails application called <code>edit_privileges</code>, in which the <code>User</code> is the "editor" and a number of other classes are "editable". Let's say that two of those classes are <code>Message</code> and <code>Comment</code>.</p>
  
  <p>My <code>EditPrivilege</code> model uses the following code:</p>
  
  <pre><code>belongs_to :editor, :class_name =&gt; "User"
  belongs_to :editable, :polymorphic =&gt; true
  </code></pre>
  
  <p>And <code>User</code>, of course</p>
  
  <pre><code>has_many :edit_privileges, :foreign_key =&gt; "editor_id"
  </code></pre>
  
  <p>In order to determine if a user has edit privileges for a certain model, I can't do the normal query:</p>
  
  <pre><code>user.edit_privileges.find_by_editable_id(@message.id)
  </code></pre>
  
  <p>because if the user has edit privileges to edit a comment with the same id as <code>@message</code>, the query will return true with the wrong edit privilege record from the table.</p>
  
  <p>So, I tried doing these options:</p>
  
  <pre><code>user.edit_privileges.find(:all, :conditions =&gt; ["editable_id = ? AND editable_type ?", @message.id, @message.class.to_s])
  user.edit_privileges.where(:editable_id =&gt; @message.id, :editable_type =&gt; @message.class.to_s)
  </code></pre>
  
  <p>which works great at finding the right record, but returns an array instead of an object (an empty array <code>[]</code> if there is no edit privilege). This is especially problematic if I'm trying to create a method to destroy edit privileges, since you can't pass <code>.destroy</code> on an array.</p>
  
  <p>I figure appending <code>.first</code> to the two above solutions returns the first object and <code>nil</code> if the result of the query is an empty has, but is that really the best way to do it? Are there any problems with doing it this way? (like, instead of using dynamic attribute-based finders like <code>find_by_editabe_id_and_editable_type</code>)</p>