2011-01-10 14 views
1

複数のアイテム(それぞれ名前と値を持つアイテム)を1つのフォームに作成しようとしています。私が持っているコードは機能していますが、空白の項目を無視する方法を理解することはできません。ここでは、コードです:Ruby on Railsですべての空白フィールドを含むモデルを無視する

#item.rb 
class Item < ActiveRecord::Base 
attr_accessible :name, :content 
validates_presence_of :name, :content 
end 

#items_controller.rb 
class ItemsController < ApplicationController 

def new 
    @items = Array.new(3){ Item.new } 
end 

def create 
@items = params[:items].values.collect{|item|Item.new(item)} 
if @items.each(&:save!) 
    flash[:notice] = "Successfully created item." 
    redirect_to root_url 
else 
    render :action => 'new' 
end 
end 

#new.html.erb 
<% form_tag :action => 'create' do %> 
<%@items.each_with_index do |item, index| %> 
    <% fields_for "items[#{index}]", item do |f| %> 
    <p> 
    Name: <%= f.text_field :name %> 
    Content: <%= f.text_field :content %> 
    </p> 
    <% end %> 
<% end %> 
<%= submit_tag %> 
<% end %> 

このコードは、すべての項目のすべてのフィールドがフォームに記入されたときに動作しますが、すべてのフィールドが空白のままにしている場合(原因の検証に)失敗しました。目標は、1つまたは2つのアイテムを空白のままにしても保存できるということです。

私は確かにこれには簡単な解決策がありますが、私は時間をかけて無駄にしてきました。どんな助けもありがとう!

+0

コントローラレベルでパラメータをフィルタリングする必要があります。 – apneadiving

+0

@apneadiving - より具体的にできますか?私はどのくらい正確にそれが動作するか分からない。ありがとう! – aguynamedloren

+0

camのコーディング方法に従うべきですが、paramsハッシュで作業する必要があります。私は一見することに同意しますが、paramsサンプルを提供してください(あなたのログを見てください) – apneadiving

答えて

1

class Item 
    def empty? 
    attributes.values.compact.empty? 
    end 
end 

# in ItemsController 
if @items.reject(&:empty?).all(&:save) 

カップルノート:

  1. save!を使用していましたが、おそらくsaveが必要です。 save!は、アイテムの1つが無効で、あなたのnewテンプレートの代わりにエラーページが表示された場合に例外を発生させます。
  2. eachallに置き換えました。 eachはあなたが意図したことをしません - すべてのアイテムが有効で保存されている場合にのみtrueを返します。 allそれだけです。
+1

助けてくれてありがとう。これはうまくいくようですが、重要なコードを含めるのを忘れてしまいました。すべてのアイテムには、プロジェクトID(<%= f.hidden_​​field:project_id%>)が事前に設定されているため、アイテムが空でないと見なされます。空の場合はプロジェクトIDの値を入力してください – aguynamedloren

+1

最後のコメントを削除しています空白のメソッドで 'attributes.values.compact.empty?'の代わりに 'name.empty?&&' content.empty?それがうまくいった - ありがとう! – aguynamedloren

1

私はこれが最善の解決策であるわからないんだけど、おそらくあなたのような何かを行うことができます:私はこれを行うだろう

@items.reject! { |item| item.attributes.values.compact.empty? } 
+1

すべてのアイテムに(フォームの隠しフィールドからの)値があらかじめ入力されているとどうなりますか?アイテムのどれもが空でないので、それらはすべて通過する...問題を提示する。空をチェックするときに、どのように特定の値を無視するのですか? – aguynamedloren

+0

その場合、モデルに 'default?'メソッドを追加するのが最善の方法でしょう(あなたが持っている事前設定された値に対してモデルの属性をチェックします)。次に、拒否行を '@ items.reject! 'に変更します。 {|アイテム| item.default? } ' – cam

関連する問題