3

誰かがこれを行うための最良の方法を教えてくれることを願っています。人々がさまざまな仕事で自分のスキル/資格をリストするためのサインアップフォームを設定しています

スキーマは、Mongoid と Inheritance を使用してこれらの線に沿っています

class Person 
  include Mongoid::Document
  field :name, :type => String 
  field :education, :type => String 
end

class Accountant < Person
  field :cpa, :type => Boolean
  field :active_cpa, :type => Boolean  
end

class SoftwareDeveloper < Person
  field :full_stack, :type => Boolean
  field :language, :type => Array  
end

そのため、ユーザーはサインアップ ページ mysite.com/persons/new にアクセスします。ここには、さまざまな仕事 (金融、エンジニアリング、マーケティングなど、さまざまな業界別にリストおよびグループ化されています) を選択するためのフォームがあり、ユーザーの選択に基づいて、より多くの仕事を選択できます。そのジョブ機能に固有の詳細ビューが表示されます。(たとえば、ソフトウェア開発者はプログラミング言語を一覧表示でき、会計士は CPA を持っている場合に一覧表示できます)。

私の質問は、コントローラーとビューレイヤーでこれを処理する最良の方法は何ですか? 私がカバーしている約 100 の異なるジョブ機能があるので、ユーザーを mysite.com/accountants/new または mysite.com/engineers/new にリダイレクトする代わりに、コントローラーとビューを組み合わせて、それぞれにコントローラー/ビューを用意したいと思います。特定の仕事。

誰かがこれにアプローチするための最良の方法を教えてくれませんか? 詳細なフォームをレンダリングするためにjQueryとおそらくいくつかのajax呼び出しを使用する必要があることはわかっていますが、最初はform_forがユーザーに関連付けられており、モデルの属性が限られているため、コントローラーをどうすればよいかわかりません。 params を取得し、より具体的なジョブの検証を使用して params ハッシュに渡します

4

1 に答える 1

2

私は最近、このような問題を抱えていました。基本タイプの Person で form_for を使用してフォームを設定することになりました。フォーム内で、基本フィールド用のフィールドセットを作成し、フィールドセット タグを分離して、各サブクラスで使用可能な追加フィールドを次のように表します。

<%= form_for @person do |f| %>

<fieldset id="base">
  <%= f.label :name %>
  <%= f.check_box :name %>
  <!-- ... -->
</fieldset>

<fieldset id="accountant">
  <%= fields_for :accountant do |f| %>
     <%= f.label :cpa %>
     <%= f.check_box :cpa %>
     <!-- ... -->
  <% end %>
</fieldset>

<fieldset id="software_developer">
  <%= fields_for :software_developer do |f| %>
     <%= f.label :full_stack %>
     <%= f.check_box :full_stack %>
     <!-- ... -->
  <% end %>
</fieldset>

fields_for をこのように使用すると、次のようなパラメーターを使用してコントローラーの「作成」メソッドを提供するフォーム POST が生成されます。

params[:person] = { :name => "Joe Smith", ... }
params[:accountant] = { :cpa => true, ... }
params[:software_developer] = { :full_stack => false, ... }

フォームには、ジョブの種類を指定する何らかの方法も必要です。私の場合、単純な select タグを使用しました。

<%= select_tag :job_type, options_for_select(@job_types) %>

これにより、コントローラに params[:job_type] が提供されます。そこから、「作成」メソッドは、ユーザーが選択したジョブの種類を把握し、正しいサブクラスを作成して、指定されたパラメーターを使用する必要があります。これにはケースステートメントを使用しました:

case params[:job_type]
when :accountant
  @person = Accountant.new(params[:person].merge(params[:accountant]))
when :software_developer
  @person = SoftwareDeveloper.new(params[:person].merge(params[:software_developer]))
when ...
end

多くのサブクラスがある場合、スケーラブルではない可能性があります。したがって、params[:job_type] が、フォームが送信する値として作成するクラスの名前を提供するように調整することができます。次に、次のようなことができます。

@person = params[:job_type].constantize.new(params[:person].merge(params[params[:job_type].underscore])

このコードは、ジョブ タイプ フィールドを使用してクラス名に変換し、再度サブクラスの正しいフィールドを見つけます。

最後に、jQuery を少し使用して、ユーザーが別のジョブ タイプを選択したときに別のフィールド セットを表示または非表示にします。これを行うには、select_tag 要素に .change() ハンドラーをアタッチし、すべてのフィールドセットを非表示にしてから、選択したジョブ タイプに一致する「id」を持つ 1 つのフィールドセットを表示します。このためのサンプル コードが必要な場合はお知らせください。

最後の仕上げとして、ジョブ固有のフィールド セットをパーシャルでレンダリングして、メイン フォームにさまざまな種類のすべてのジョブをレンダリングするための一連の呼び出しだけを含めることを考えるかもしれません。

これを行うためのより良い方法があるかどうかはわかりませんが、このアプローチは私にとって非常にうまく機能し、単一のコントローラーと一連のビューを使用して、親/子サブクラス ツリー全体の作成と編集を管理することができました。

于 2012-05-17T22:08:00.957 に答える