2017-05-31 13 views
0

私は従業員ビューを持っています。ここには、すべてのスキルがリストされています。スキルテーブルには、自分のdbのスキルテーブルに書き込まれています。すべての従業員に対して、必要な場合と同様に、すべてのスキルが表示されます。Rails、このn + 1を解決するためのヒント?

従業員とスキルは、多くの場合:関連付けを伴って相互に関連しています。

class Employee < ApplicationRecord 
    has_many :employeeskillsets, foreign_key: "employee_id" 
    has_many :skills, through: :employeeskillsets 
end 

class Skill < ApplicationRecord 
    has_many :employeeskillsets, foreign_key: "skill_id" 
    has_many :employees, through: :employeeskillsets 
end 

class Employeeskillset < ApplicationRecord 
    belongs_to :employee, foreign_key: 'employee_id' 
    belongs_to :skill, foreign_key: 'skill_id' 
end 

すべてのこれらのスキルは(あたり余分に必要コミットしない、削除/直接挿入]をクリックします)、その従業員にその特定のスキルを無効/有効にするためにトグルされているボタンとして表示されます。

<%= link_to apply_skill_employee_path(employee: @employee, skill_id: skill.id), method: :put, remote: :true do %> 
<%= skill.name %></div><% end %> 

ただし、ページを読み込むと、ボタンが色付きで表示されます。スキルが既に有効になっている場合は、ボタンの色は緑、灰色でなければなりません。そしてここに私の問題が始まります: 私のアプリは、それぞれのスキルを1つの別個のselectステートメントでチェックします。私はこれに次のコードを使用します:

<%= link_to apply_skill_employee_path(employee: @employee, skill_id: skill.id), method: :put, remote: :true do %> 
    <% if @employee.skills.exists?(skill.id) %> 
    <div class="button skill e-true"><%= skill.name %></div> 
    <% else %> 
    <div class="button skill"><%= skill.name %></div> 
    <% end %> 

私はすでにインクルードを使用しようとしましたが、存在するようですか?各スキルを個別にチェックします。

誰かがここで提案をしていますが、どのように私はこれを解決できましたか?

おかげさまで、私はすべてが必要であると言いたいと思います。

編集1:私は部分的にこれを表現することを忘れています(これは知っておくことが重要な場合)。 ここに、employees_controllerの@employee varで使用されているものがあります。

@employee = Employee.find_by(id: params[:id]) 

答えて

0

pluck INGのIDを試してみてください、そして、あなたがこれを避けるために、追加のクエリも

<% if @employee.skill_ids.exists?(skill.id) %> 

を起動しませんskills

<% skills = @employee.skills.pluck(:id) %> 
<%= link_to apply_skill_employee_path(employee: @employee, skill_id: skill.id), method: :put, remote: :true do %> 
<% if skills.include?(skill.id) %> 
    <div class="button skill e-true"><%= skill.name %></div> 
<% else %> 
    <div class="button skill"><%= skill.name %></div> 
<% end %> 
+0

@maxご丁寧にご教示ください。afaikスコープクエリーDBもあります。 –

0

skillもアクティブレコードモデルですので、あなたは従業員が特定のスキルを持っているかどうかを確認するために、従業員のスキルコレクションにinclude?を使用することができます。

@employee.skills.include?(skill) 

ロード・従業員のスキルを熱心にするincludes句を自由に使用することがこの方法です。

0

のすべての属性を取得する必要がないようinclude?をチェック次の行のn+1

apply_skill_employee_path(employee: @employee, skill_id: skill.id) 

はあなたがRailsの道ははるかに簡単であるskills

@employee = Employee.includes(:skills).where(......) 
0

を含めていることを確認します。また、これは:throughオプションと間接的にassocationsで動作します

@employee.skills_ids = [1,2,3] 

:あなたはActiveRecordの中has_manyマクロを使用する場合

が、それはまた、配列との関係を追加または削除するために使用することができ_idsメソッドを作成します。

選択したり、チェックボックスのタグを作成するフォームコレクションヘルパーと一緒にこれを使用することができます。

<%= form_for(@employee) do |f| %> 
    <%= f.label :skill_ids, 'Skills' %> 
    <%= f.collection_check_boxes(:skills_ids, Skill.all, :id, :name) %> 
<% end %> 

あなたは左の外側を行うことができ、余分なクエリを回避するためには、コントローラに参加:

def edit 
    # left_outer_joins is new in Rails 5 
    # see https://blog.bigbinary.com/2016/03/24/support-for-left-outer-joins-in-rails-5.html 
    @employee.left_outer_joins(:skills).find(params[:id]) 
end 

通常のアップデートとして扱われるべきものについては、コントローラに愚かな余分なメソッドは必要ありません。キッス。

+0

これは実際に自分のコードをきれいにするでしょうが、私はこれを次のように構成されたカテゴリ内でどのように使用できるのか分かりません。カテゴリ:{スキル、サブカテゴリ:{スキル}}} – Fast

+0

これはあまり最適ではないレイアウトのようです - あなたは本当に1つのカテゴリモデルを必要とし、階層化を構築するために自己結合する必要があります。しかし、全く別の問題です。 – max

+0

私はちょうどあなたが私を助けることができるなら、それのための新しい質問を作成した、素晴らしいだろう。 https://stackoverflow.com/questions/44324189/rails-category-as-self-referenced-model – Fast

関連する問題