Dry Measurement Methods

I am using Ruby on Rails 3.0.7, and I would like to use the DRY methods (don't repeat it myself).

In the model file, I have:

class Articles::Category < ActiveRecord::Base scope :article_related_to, lambda { |user| where('articles_categories_article_relationships.user_id = ?', user.id) } scope :comment_related_to, lambda { |user| where('comments_articles_article_category_relationships.user_id = ?', user.id) } has_many :comment_article_category_relationships has_many :comments, :class_name => 'Comments::Articles::ArticleCategoryRelationship', :through => :comment_article_category_relationships, :source => :comment has_many :article_relationships :class_name => 'Articles::Categories::ArticleRelationship', has_many :articles, :through => :article_relationships, :source => :article end 

Using the code above, I can do this:

 @comment.article_categories.comment_related_to(@current_user) @comment.article_categories.article_related_to(@current_user) 

How can I use the :article_related_to methods to do both :article_related_to and :comment_related_to use something like the following

 @comment.article_categories.related_to(@current_user) # In order to pass the correct "context" 'article' or 'comment' I thought # something like # # @comment.article_categories.related_to(@current_user, 'article') # @comment.article_categories.related_to(@current_user, 'comment') # # but, maybe, there is a way to retrieve automatically that "context" so to # write only one "DRYed" scope method. 

+4
source share
1 answer

The best I can offer is this:

 scope :related_to, lambda { |user, context| tbl = context == :article ? :articles_categories_article_relationships : :comments_articles_article_category_relationships where("#{tbl}.user_id = ?", user.id) } 

This gives you @comment.article_categories.related_to(@current_user, :article) , as you suggested. But I agree with Max Williams. This confuses your code unnecessarily without real gain.

If you really want to confuse your code further, you can do this:

 def self.method_missing(method, *args) if method =~ /^(.*)_related_to$/ related_to(*args, $1) else super end end def self.related_to(user, context) through = reflections[context.to_s.pluralize.to_sym].options[:through] tbl = reflections[through].options[:class_name].underscore.pluralize.gsub('/', '_') where("#{tbl}.user_id = ?", user.id) end 

Please note that I believe your associations have a couple of typos. Probably should be:

 has_many :comment_article_category_relationships, :class_name => 'Comments::Articles::ArticleCategoryRelationship' has_many :comments, :through => :comment_article_category_relationships, :source => :comment has_many :article_relationships, :class_name => 'Articles::Categories::ArticleRelationship' has_many :articles, :through => :article_relationships, :source => :article 
+1
source

All Articles