使用控制器中的for循环同时创建多个对象

时间:2014-06-10 17:12:41

标签: ruby-on-rails ruby-on-rails-3

我有一个Word模型,其中包含一列:word。我有一个表单,可以在提交时创建一个@word对象。

字/ _form.html.erb

<%= form_for(@word, :remote => (params[:action] == 'new' ? true : false)) do |f| %>
  <fieldset>
    <div class="field">
      <%= f.text_field :word, :required => true %>
    </div>
  </fieldset>

  <div class="actions">
    <%= f.submit :disable_with => 'Submitting...' %>
  </div>
<% end %>

字/ create.js.erb

$('#words').prepend( '<%= escape_javascript(render @word) %>' );
$('#new-word-form-container').find('input:not(:submit),select,textarea').val('');

我想在一个表单提交上同时快速创建多个单词(即不必重新提交以创建每个单词)。

我的Word模型中有一个方法将字符串拆分为单词数组(用逗号或空格分隔)。

class Word < ActiveRecord::Base

attr_accessible :word

  # Split Words method splits words seperated by a comma or space
  def self.split_words(word)
    # Determine if multiple words
    if word.match(/[\s,]+/)
      word = word.split(/[\s,]+/)    # Split and return array of words
    else 
      word = word.split              # String => array 
    end 
  end

end

我尝试在create操作中使用for循环来遍历每个数组元素,并为元素创建一个@word对象。

class WordsController < ApplicationController
respond_to :js, :json, :html

def create
  split = Word.split_words(params[:word])

  split.each do |w|
    @word = Word.create(params[:w])
    respond_with(@word)
  end
end

我目前收到HashWithIndifferentAccess错误,如下所示。

Started POST "/words" for 127.0.0.1 at 2014-06-10 13:09:26 -0400
    Processing by WordsController#create as JS
      Parameters: {"utf8"=>"✓", "authenticity_token"=>"0hOmyrQfFWHRkBt8hYs7zKuHjCwYhYdv444Zl+GWzEA=", "word"=>{"word"=>"stack, overflow"}, "commit"=>"Create Word"}
    Completed 500 Internal Server Error in 0ms

    NoMethodError (undefined method `match' for {"word"=>"stack, overflow"}:ActiveSupport::HashWithIndifferentAccess):
      app/models/word.rb:9:in `split_words'
      app/controllers/words_controller.rb:36:in `create'

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

在单词控制器中的create操作中,您可以从params中获取单词,该单词会返回parameter个对象。 parameter对象是继承自hash的类似ActiveSupport::HashWithIndifferentAccess的对象。然后,您尝试在match对象上调用parameter方法,但它不知道如何回复它,因此您获得了NoMethodError

结帐http://api.rubyonrails.org/classes/ActionController/Parameters.html

您需要做的第一件事是传递params[:word][:word]而不是params[:word],这应该会返回一个string对象,此方法现在可以正常工作。

由于each create可能会返回params[:w],因此您可能会在nil w循环中遇到另一个问题。您应该只传入array,因为这将是您正在迭代的word中的每个单词,如果没有记错,您想为每个单词创建一个def create split = Word.split_words(params[:word][:word]) @words = split.map do |w| Word.create(word: w) end respond_with(@words) end 对象。

{{1}}

答案 1 :(得分:0)

class WordsController < ApplicationController

  respond_to :js, :json, :html

  def create
    @words = params[:word].split.map { |word| Word.create(word) }
    respond_with(@words)
  end
end