Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted
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
share|improve this answer
1  
first_or_create considered to be a clearer alternative for find_or_create_by_xxx –  Alexey Apr 24 '12 at 19:54
    
@Alexey it had the same bug, overriding find_or_create_by_xxx was a better option. Thanks for the tip. –  Can Hanhan Apr 29 '12 at 11:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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