1
\$\begingroup\$

I have three tables

class User < AR::Base
  has_many :lexemes, :dependent => :destroy
end

class Lexeme < AR::Base
  belongs_to :user
  belongs_to :word
end

class Word < AR::Base
  has_many :lexemes
end

This code is storing the word to Words table and assign it to the user.

word = Word.where(:word=>token).first_or_create
lexeme = @user.lexemes.where(:word_id=>word.id).first_or_create

I don't like my code, so is it possible to improve it? Thanks

\$\endgroup\$
1
\$\begingroup\$
class User < AR::Base
  has_many :lexemes, :dependent => :destroy
  has_many  :words, :through => :lexemes
end

class Lexeme < AR::Base
  belongs_to :user
  belongs_to :word
end

class Word < AR::Base
  has_many :lexemes
  has_many :users, :through => :lexemes
end

You should normally be able to create word by following code but it seems there is a bug in Rails.

word = @user.words.find_or_create_by_word(token)

Therefore I have changed the model to following. You may remove it when the bug is fixed.

class User < ActiveRecord::Base
  has_many :lexemes
  has_many :words, :through => :lexemes do
        def find_or_create_by_word(token)
            find_by_word(token) || create(:word => token)
        end
  end
end
|improve this answer|||||
\$\endgroup\$
  • 1
    \$\begingroup\$ first_or_create considered to be a clearer alternative for find_or_create_by_xxx \$\endgroup\$ – Alexey Apr 24 '12 at 19:54
  • \$\begingroup\$ @Alexey it had the same bug, overriding find_or_create_by_xxx was a better option. Thanks for the tip. \$\endgroup\$ – Can Hanhan Apr 29 '12 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.