Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So if you're using the acts-as-taggable-on gem and have the following models:</p> <pre><code>class User &lt; ActiveRecord::Base acts_as_tagger has_many :brand_users has_many :brands, :through =&gt; :brand_users end </code></pre> <p>So you also have the tables in your schema like:</p> <pre><code>create_table "users", :force =&gt; true do |t| t.string "name" end create_table "brands", :force =&gt; true do |t| t.string "name" end </code></pre> <p>Then the following SQL query should hopefully do what you want (?):</p> <pre><code>SELECT brands.* FROM brands WHERE brands.id NOT IN ( SELECT brands.id FROM brands INNER JOIN brand_users ON brand_users.brand_id = brands.id INNER JOIN taggings ON (taggings.tagger_id = brand_users.user_id AND taggings.tagger_type = 'User') WHERE brand_users.user_id = 1 AND taggings.taggable_id = brand_users.brand_id ) </code></pre> <p>To translate this into Rails ORM, I can't get any closer without hard coding the whole sub-select SQL string, something like:</p> <pre><code>class Brand &lt; ActiveRecord::Base has_many :brand_users has_many :users, :through =&gt; :brand_users scope :has_not_been_tagged_by_user, lambda {|user| where("brands.id NOT IN (SELECT brands.id FROM brands INNER JOIN brand_users ON brand_users.brand_id = brands.id INNER JOIN taggings ON (taggings.tagger_id = brand_users.user_id AND taggings.tagger_type = 'User') WHERE brand_users.user_id = ? AND taggings.taggable_id = brand_users.brand_id)", user.id) } end </code></pre> <p>(I know you could do this and then use ruby's <a href="https://stackoverflow.com/questions/4307411/not-in-rails">.map(&amp;:id).join(',')</a> but if this is a large app I think you loose a lot of performance by taking this out of the database, converting it into a string of integers and feeding it back in (as I understand it).)</p> <p>Then in your controller <strong>I think</strong> you'd do something like:</p> <p><code>@brand = current_user.brands.has_not_been_tagged_by_user(current_user)</code></p> <p>As an aside, I think this would actually then execute an SQL like below (is that right?):</p> <pre><code>SELECT brands.* FROM users INNER JOIN brand_users ON brand_users.user_id = users.id INNER JOIN brands ON brands.id = brand_users.brand_id WHERE brands.id NOT IN ( SELECT brands.id FROM brands INNER JOIN brand_users ON brand_users.brand_id = brands.id INNER JOIN taggings ON (taggings.tagger_id = brand_users.user_id AND taggings.tagger_type = 'User') WHERE brand_users.user_id = 1 AND taggings.taggable_id = brand_users.brand_id ) AND users.id = 1 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload