2011-07-12 5 views
4

私はRuby on Rails 3.0.7を使用しています。私は自分のスコープのメソッドをDRY(自分自身を繰り返さないでください)したいと思います。私はこれを行うことができます上記のコードを使用することによりDRYスコープのメソッド

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 

::私が持っているモデルファイルで

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

用可能にするためにはどうすればよい「DRY」スコープ法:article_related_to:comment_related_toの両方を使用すると、次のようなものが使用されます。

@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. 

?あなたは提案のようにあなたに@comment.article_categories.related_to(@current_user, :article)を与える

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

+1

私の目は、この事をまっすぐに保つことを試みているだけです!とにかく@current_userオブジェクトを使って探しているものを得ることができますか? – dogenpunk

+0

@dogenpunk - BTW: "私の目は、このことを真っ直ぐ保つために疲れている!" ...どういう意味ですか? - 私の場合、私は '@current_user'オブジェクトを通して私が探しているものを得ることができますが、この反対側では、質問に記述されているのと同じ問題があります。 – Backo

+1

私はこれが個人的にDRYだと思います。私にとっては可読性がDRYを上回り、これによりコードを読みにくくしています。 DRYは、コードの行を最小化するのではなく、機能や値などを単一の場所に保存することが重要です。 –

答えて

1

私が提供できる最高は次のとおりです。しかし私はマックス・ウィリアムズと契約している。これは、あなたのコードを不必要に難読化することなく、難しくします。

あなたは、さらにあなたがこれを行うことができ、あなたのコードを難読化するために、本当に熱望している場合:

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 

を私はあなたの団体は、タイプミスのカップルを持っていると信じていますのでご注意ください。おそらくそうでなければなりません:

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 
関連する問題