14

Rails 2 アプリケーションを Rails 3 に変換するには、gem のsearchlogicを置き換える必要があります。今、Rails 3.2.8 と gem Ransackを使用して、既存のスコープを使用する検索フォームを作成したいと考えています。例:

class Post < ActiveRecord::Base
  scope :year, lambda { |year| 
    where("posts.date BETWEEN '#{year}-01-01' AND '#{year}-12-31'") 
  }
end  

私の知る限り、これはカスタムransackerを定義することで実現できます。残念ながら、これに関するドキュメントは見つかりません。Post私はクラスでこれを試しました:

ransacker :year, 
          :formatter => proc {|v| 
            year(v)
          }

しかし、これは機能しません:

Post.ransack(:year_eq => 2012).result.to_sql
=> TypeError: Cannot visit ActiveRecord::Relation

宣言のバリエーションをいくつか試しransackerましたが、どれも機能しません。助けが必要です...

更新:上記の範囲は単なる例です。Ransack 内のすべての既存のスコープを使用する方法を探しています。Ransack の前身である MetaSearch には、search_methodsスコープを使用するために呼び出される機能があります。Ransack は、これをそのままではまだサポートしていません。

4

3 に答える 3

1

Ransack では、このためのカスタム述語を作成できます。残念ながら、ドキュメントには改善の余地がありますが、チェックアウトしてください: https://github.com/ernie/ransack/wiki/Custom-Predicates

また、あなたが取り組もうとしている問題は、彼らの問題トラッカーに掲載されていると思います。そこでは良い議論が行われています: https://github.com/ernie/ransack/issues/34

于 2012-10-18T10:07:24.567 に答える
0

パラメータをアクティブな関係スコープに変換するのに役立つsiphonという gem を作成しました。ransack と組み合わせると、これを実現できます。

ここで完全な説明を読むことができます。その間、ここにそれの要点があります

景色

= form_for @product_search, url: "/admin/products", method: 'GET' do |f|
  = f.label "has_orders"
  = f.select :has_orders, [true, false], include_blank: true
  -#
  -# And the ransack part is right here... 
  -#
  = f.fields_for @product_search.q, as: :q do |ransack|
    = ransack.select :category_id_eq, Category.grouped_options
```

わかりましたのでparams[:product_search]、スコープを保持しparams[:product_search][:q]、ランサックの良さを備えています。ここで、そのデータをフォーム オブジェクトに配布する方法を見つける必要があります。そのため、まず ProductSearch にコントローラーでそれを飲み込ませます。

コントローラー

# products_controller.rb
def index
  @product_search = ProductSearch.new(params[:product_search])
  @products ||= @product_formobject.result.page(params[:page])
end

フォーム オブジェクト

# product_search.rb
class ProductSearch
  include Virtus.model
  include ActiveModel::Model

  # These are Product.scopes for the siphon part
  attribute :has_orders,    Boolean
  attribute :sort_by,       String

  # The q attribute is holding the ransack object
  attr_accessor :q

  def initialize(params = {})
    @params = params || {}
    super
    @q = Product.search( @params.fetch("q") { Hash.new } )
  end

  # siphon takes self since its the formobject
  def siphoned
    Siphon::Base.new(Product.scoped).scope( self )
  end

  # and here we merge everything
  def result
    Product.scoped.merge(q.result).merge(siphoned)
  end
end
于 2013-12-22T12:22:49.380 に答える