I am using Ruby on Rails 3.0.7 and I would like to DRY (Don’t Repeat Yourself) my scope methods.
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
By using the above code I can do this:
@comment.article_categories.comment_related_to(@current_user)
@comment.article_categories.article_related_to(@current_user)
How can I “DRY” scopes methods in order to make possible for both :article_related_to and :comment_related_to 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.
?
The best I can offer is the following:
That gives you the
@comment.article_categories.related_to(@current_user, :article)like you suggested. But I’m in agreement with Max Williams. This obfuscates your code unnecessarily with no real gain.If you are really eager to obfuscate your code further you can do this:
Please note that I believe your associations have a couple of typos. Probably should be: