2011-01-10 4 views
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

캠의 코딩 방법을 따라야하지만 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!은 항목 중 하나가 유효하지 않은 경우 예외를 발생시키고 new 템플릿 대신 오류 페이지가 표시됩니다.
  2. eachall으로 바꿨습니다. each은 의도 한대로 처리하지 않을 것입니다. 즉, 모든 항목이 유효화되고 저장된 경우에만 true을 반환해야합니다. all 그냥 않습니다.
+1

도움을 주셔서 감사합니다. 이것은 효과가있는 것처럼 보이지만 중요한 코드를 포함하는 것을 잊었다는 것을 깨달았습니다. 모든 항목은 양식의 프로젝트 ID (<% = f.hidden_field : project_id %>)로 미리 채워집니다. 따라서 항목이 비어있는 것으로 간주됩니다.이 문제를 해결할 수있는 방법은 무엇입니까? 공백을 검사 할 때 프로젝트 ID 값을 입력 했습니까? – aguynamedloren

+1

마지막 코멘트를 잊어 버렸습니다. 알아 냈습니다. empty.metadata에 '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 | item.default? } ' – cam

관련 문제