3

会社は、既に持っているエントリを検索することでオートコンプリートできます。https://github.com/crowdint/rails3-jquery-autocomplete gemを使用して、追加しました

autocomplete :company, :name, :scopes => [:distinct]

私のコントローラーに、私のモデルには次のものがあります:

scope :distinct, lambda { select("companies.name").uniq }

「Merce」という用語を使用しても、私のシステムはメルセデス ベンツの 5 つのエントリすべてを返します。SQL:

35mCompany Load (4.0ms)[0m  SELECT DISTINCT companies.name, companies.id FROM "companies" WHERE (LOWER(companies.name) ILIKE 'merce%') ORDER BY companies.name ASC LIMIT 10

私が試したさまざまなこと:

select(:name).uniq  => Not unique values
distinct("companies.name") => Wrong number of arguments
group(:id, :name) => Not unique values
group(:id, :name).uniq  => Not unique values

ただし、コントローラーで select ステートメントを使用すると (オートコンプリートなしで) 機能します。

@companies = Company.select(:name).uniq => Perfect results

この宝石内で正しいクエリを作成する方法についての説明を探しています。

4

3 に答える 3

4

上記の Chischaschos がすでに述べたように、コントローラーのアクションを再定義することが最善の方法です。私は Heroku で PostgreSQL を使用しているため、Thuss (Thodd Huss) によって開発されたより複雑なルートを使用する必要がありました。

現在のプラグインの機能を超えるカスタム オートコンプリート (個別のエンティティの選択など) が必要な場合は、コントローラーに独自のオートコンプリート メソッドを実装します。これは、通常コントローラーに入れる "autocomplete :organization, :city" 呼び出しを置き換えるだけです。たとえば、「異なる」都市をオートコンプリートするには、次のようにします。

def autocomplete_organization_city
 term = params[:term]
 if term && !term.empty?
  items = Organization.select("distinct city").
      where("LOWER(city) like ?", term.downcase + '%').
      limit(10).order(:city)
 else
 items = {}
 end
render :json => json_for_autocomplete(items, :city)
end

SQLite のユーザー向けに、はるかに短いソリューションもあります。ここで元のスレッドを見つけてください: https://github.com/crowdint/rails3-jquery-autocomplete/issues/25

于 2012-11-06T13:25:55.983 に答える
4

その宝石によって生成されるクエリ:

Company Load (4.0ms)  SELECT DISTINCT companies.name, companies.id FROM "companies" WHERE (LOWER(companies.name) ILIKE 'merce%') ORDER BY companies.name ASC LIMIT 10

テーブルのプライマリ ID とオートコンプリートされるフィールドの名前が常に含まれます。その答えは、このメソッドの 36 行目と 37 行目にあります。

def get_autocomplete_select_clause(model, method, options)
  table_name = model.table_name
  (["#{table_name}.#{model.primary_key}", "#{table_name}.#{method}"] + (options[:extra_data].blank? ? [] : options[:extra_data]))
end

そのクエリ結果はすでに一意です (個別の名前 + ID を使用します)。これを回避するには、次の 2 つの方法が考えられます。

  1. サブクエリを使用してクエリを作成します。アイデアは、一意の結果を返す最初のクエリを作成し、次にそれをテーブル ID で外部結合し、その ID で一意の名前を返すことです。

  2. コントローラーで、結果を取得するアクションを再定義して、必要なことを何でも実行できるようにします。実際、この gem が行うことは、メタ プログラミングを使用してコントローラに autocomplete_model_attribute アクションを追加することです (ソース コードを参照)。

これが役立つかどうかを教えていただければ幸いです。詳細が必要な場合はお知らせください。

于 2012-10-23T13:39:50.417 に答える