2011-12-12 10 views
0

Ruby/Railsの新機能ですが、私には多くの「魔法」が含まれています。これは素晴らしいことかもしれませんが、なぜ何かが動作するか(この場合は)動作しないのかを理解することが非常に難しくなります。私の問題は、フォームフィールドをどのように名前付け/構成して、「うまくいく」ようにすることです。Ruby/Railsアプリケーションでのフォームフィールドの名前付け/生成に問題がある

データセット、要件、モジュール、および構成(データセット、module_requirements、mods、およびmodule_configurationsという名前の)の4つの主なオブジェクトがあります。モジュールには要件(多対多)があり、特定の要件(多対1)を満たす複数のデータセットが存在する場合があります。モジュールには多くの構成(1対多)があります。これらの関係を通じて、Configurationが多くのデータセット(多対多)に関連付けられることがわかります。特定のConfigurationと特定のDatasetとの実際の関連付けは、has_and_belongs_to_many関係で管理されます。

私は、関連するモジュールの要件をフルフィルするために使用するデータセットを選択することで、ユーザーが構成を編集できるようにするためのインターフェースを作成しています。

したがって、ユーザーは構成ページにあり、各要件ごとに1つのドロップダウンボックスの一覧が表示されます。ドロップダウンはそれぞれ、所要量を満たすことができるさまざまなデータセットで満たされています。私の問題は、フォームが送信されるときに選択したデータセットが保存されるように、フォームフィールドをどのように構造化するのか分かりません。

==> The basic data model in more detail: 

class Dataset < ActiveRecord::Base 
    belongs_to :module_requirement 
    has_many :mods, :through => :module_requirement 
    has_many :module_configurations, :through => :mods 
end 

class ModuleRequirement < ActiveRecord::Base 
    belongs_to :dataset_type 
    has_and_belongs_to_many :mod 
    has_many :module_configuration, :through => :mod, :source => :module_configurations 
    has_many :dataset 
end 

class Mod < ActiveRecord::Base 
    validates :name,  :presence => true 
    validates :description, :presence => true, 
          :length => { :minimum => 5 } 

    has_and_belongs_to_many :module_requirements 
    has_many :module_configurations 
    has_many :datasets, :through => :module_requirements 
end 

class ModuleConfiguration < ActiveRecord::Base 
    belongs_to :mod 
    has_many :module_requirements, :through => :mod 
    has_and_belongs_to_many :datasets 
end 

==> From module_configurations_controller.rb: 

def edit 
    @module_configuration = ModuleConfiguration.find(params[:id]) 

    # List datasets by their requirements to provide a drop down box for each requirement listing only relevant datasets 
    @datasetsByReq = Hash.new 

    Dataset.all.collect{ |d| if(!d.module_requirement.nil?) 
           @datasetsByReq[d.module_requirement.id] ||= Array.new # Create an empty array if needed 
           @datasetsByReq[d.module_requirement.id].push(d)   # Append config to the array 
          end } 

    # Find the selected dataset for each requirement        
    @selectedDataset = Hash.new 
    @module_configuration.datasets.all.collect{ |d| @selectedDataset[d.module_requirement.id] = d} 
end 


def update 
    @module_configuration = ModuleConfiguration.find(params[:id]) 

    respond_to do |format| 
     if @module_configuration.update_attributes(params[:module_configuration]) 
     format.html { redirect_to @module_configuration, notice: 'Module configuration was successfully updated.' } 
     format.json { head :ok } 
     else 
     format.html { render action: "edit" } 
     format.json { render json: @module_configuration.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

==> From module_configurations/edit.html.erb 

<%= simple_form_for(@module_configuration) do |f| %> 

    ... other fields here ... 

    <!-- Produce one dropdown filled with datasets per requirement: --> 
    <% config.mod.module_requirements.each do |req| %> 
    <%= f.fields_for :datasets , req do |r|%> 

     <% selected = @selectedDataset[req.id].nil? ? -1 : @selectedDataset[req.id].id%>    <== Problem is likely here... 

     <%= collection_select :requirement_id, :dataset_id, @datasetsByReq[req.id] || [], :id, :name, <== ...and/or here 
         :include_blank => 'None specified', :selected => selected %> 
    <% end %> 
    <% end %> 
<% end %> 

module_configurationを編集する場合、ユーザーは各要件のデータセットを選択できる必要があります。上記のコードはドロップダウンを作成しますが、フォームの送信時にデータが保存されるように名前を付けるものを特定できません。

すべての最新リリースを使用して、Linuxで実行しています。

ご協力いただきありがとうございます!


解決策を探していなくても、別のメカニズムで解決できます。私は、問題がcollection_selectの名前付け方法に関連していることを確認しましたが、完全な説明は非常に難解で具体的でコミュニティにとって役に立たないと思います。

+0

質問をより簡潔にできますか? – Snips

+0

私は「肥大化した質問」バッジのために行っていました! – Watusimoto

答えて

0

私はあなたのモデルの論理を理解するのに少し苦労しています。なぜなら、これらのクラスの間には多くの関係があり、現時点では私の頭を包み込むのが難しいからです。しかし、あなたのフォームが関係を使ってあなたのモデルと正しく動作しているなら、あなたは大丈夫でしょう。

保存するフォームの取得に問題がある場合は、ネストしたの属性またはモデルを現在のモデルとの関係で保存する必要があることをモデルで知る必要があります。あなたのモデルで、次のコマンドでこれを実行します。

accepts_nested_attributes_for :relationship_name 

がそう例えば、一つのクラスはこれを好むかもしれない:

class ModuleConfiguration < ActiveRecord::Base 
    belongs_to :mod 
    has_many :module_requirements, :through => :mod 
    has_and_belongs_to_many :datasets 
    accepts_nested_attributes_for :datasets 
end 

これは関係のデータを保存するために、あなたのモデルに必要なメソッドが追加されますモデル。私が持っているもう1つの経験則は、実際にあなたのフォームでループを使うべきではないということです。これは、f.fields_for :relationship_nameが関係を自動的にループするためです。 Railsでは、穀物を扱うように感じるたびに、通常は簡単な方法で実行できます。

関連する問題