2012-03-16 8 views
0

を参照することなく、ActiveRecordの中の前:アイデアはあなたが任意のActiveRecordの::基本サブクラスに、次の以前の機能をミックスインできるということで、、私はスコープは、このような含めるモジュールで定義されている列

module ActsAsAdjacent 

    def self.included(base) 

    base.send(:scope, :next, lambda {|id| {:conditions => ["id > ?",id], 
     :order => "id ASC", :limit => 1}}) 

    base.send(:scope, :previous, lambda {|id| {:conditions => ["id < ?",id], 
     :order => "id DESC", :limit => 1}})  
    end 

。 (上記は、周囲に浮かぶいくつかの例の変形です)。

明らかなのは、特定の列 'id'を想定していますが、その列が存在しない場合や、使用されているソート順が異なる場合があることです。

現在のソート順が何であっても、またはdb内でレコードがどのようにレイアウトされているかに基づいて、次に行う方法はありますか?したがって、次の場合は例えば

class User < ActiveRecord::Base 

    default_scope :order => 'users.name ASC' 

    include ActsAsAdjacent 

ActsAsAdjacentが自動的に前の、次返すために、そのソート順を使用します。


私はいつもIDは存在すると思いますが、それはソートされていない可能性があります。

+0

実際には、次のスコープはそのdefault_scopeのidには機能しません。この場合、常に最初の名前のレコードがアルファベット順に返されます。それを理解できません。 – Mark

+0

Your:nextと:previousメソッドはスコープではありません。それらは単一のメソッドを返すだけなので、実スコープのようなクラスではなく、インスタンスで呼び出される必要があります。 – noodl

答えて

1

私はスコープの誤用だと思います。これはどう?

module ActsAsAdjacent 
    def next_by(column) 
    self.class.where("#{column} > ?", send(column)).order(column).first 
    end 

    # .. and the obvious inverse for previous_by 
end 

# Call it like this: 
some_user.next_by(:id) 
+0

それは動作しています - なぜ列名を文字列として渡すのかわかりません。 (しかたがない)。上記の私の範囲は誤用だと言います。それを理解しようとしています。 tadmanの答えの範囲が有効である理由を次に説明してください:http://stackoverflow.com/questions/5897196/rails-named-scope-in​​heritance – Mark

+0

その他の質問の答えは、あなたのメソッドは 'some_user.next_by(属性)'インスタンス上で呼び出されますが、 'User.by_name(name)'というクラスに対して直接呼び出されます。理にかなっている? – noodl

関連する問題