Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>first you should consider to use rails/activerecord conform relations. This means the foreign key in the text_translations table should be called text_id</p> <p>Create your models and associations like this:</p> <pre><code>class Text &lt; ActiveRecord::Base # all possible translations! has_many :text_translations scope :with_translation_for, lambda { |lang| { :select =&gt; "texts.*, tt.translation", :joins =&gt; "LEFT OUTER JOIN text_translations AS tt ON tt.text_id = texts.id AND tt.locale = #{ActiveRecord::Base.sanitize(lang)}" }} # return nil if translation hasn't been loaded, otherwise you get a nasty NoMethod exception def translation read_attribute(:translation) end end </code></pre> <p>and</p> <pre><code>class TextTranslation &lt; ActiveRecord::Base # every translation belongs to a text belongs_to :text # define a scope for the language scope :language, lambda { |lang| where(['locale = ?', lang]) } end </code></pre> <p>How to use:</p> <pre><code>texts = Text.with_translation_for('en') texts.each do |c_text| unless c_text.translation.nil? puts c_text.translation else puts "No translation available!" end end </code></pre> <p>Now to the pro and cons, the way using LEFT OUTER join will load you <em>all</em> texts even if there isn't a translation for a text in the desired language. The con is that you won't get the "TextTranslation" model object.</p> <p>Anotherway is to load only the text which have the desired translation. You can do it like:</p> <pre><code>texts = Text.includes(:text_translations).where(:text_translations =&gt; {:locale =&gt; 'en'}) </code></pre> <p>now <code>texts[i].text_translations</code> will return an array with all TextTranslations model object for this text matching the locale 'en'. But texts without a translation in the locale "en" won't show up.</p> <p><strong>Edit</strong></p> <p>Connected to your comment:</p> <p>The problem about using <code>.join(:tablename)</code> on a relation is that, it will result in an INNER JOIN so this is not an option. You have to explicitly declare the LEFT join. Another thing is that if you use something like <code>Text.includes(:text_translations).where(['text_translations.locale = ?', 'en'])</code> the condition will be applied to the SQL query as whole and not on the possible LEFT join itself. What you actually can do is to declare associations like </p> <pre><code>has_many :english_translations, :class_name =&gt; 'TextTranslation', :conditions =&gt; ['locale = ?', 'en'] </code></pre> <p>This way you can manage to load only english translations by eager loading (without any joins at all):</p> <pre><code>Text.includes(:english_translations).all </code></pre> <p>Checkt this out:</p> <ul> <li><a href="http://guides.rubyonrails.org/active_record_querying.html#joining-tables" rel="nofollow">Ruby On Rails Guide about Joining Tables</a></li> <li><a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html" rel="nofollow">ActiveRecord Association Docs, Search for LEFT OUTER JOIN</a></li> </ul>
 

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