Reputation: 1173
I have a Word model with one column: word. I have a form that creates an @word object when submitted.
words/_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 %>
words/create.js.erb
$('#words').prepend( '<%= escape_javascript(render @word) %>' );
$('#new-word-form-container').find('input:not(:submit),select,textarea').val('');
I'd like to shorthand the creation of multiple words simontaniously on one form submission (i.e. instead of having to resubmit to create each individual word).
I have a method in my Word model that splits the string into an array of words (separated by a comma or space).
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
I'm trying to use a for loop within my create
action to step through each array element, and create an @word object for the element.
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
I'm currently getting a HashWithIndifferentAccess error, as listed below.
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'
Any help is greatly appreciated.
Upvotes: 1
Views: 1440
Reputation: 138
In your create
action in the words controller, you fetch the words from the params
which gives you back a parameter
object. The parameter
object is a hash
like object that inherits from ActiveSupport::HashWithIndifferentAccess
. Then you try and call the match
method on your parameter
object and it does not know how to respond to it, so you get a NoMethodError
.
Checkout http://api.rubyonrails.org/classes/ActionController/Parameters.html
The first thing you need to do is pass params[:word][:word]
instead of params[:word]
, this should give you back a string
object and this method should now work.
It also looks like you might run into another problem in the each
loop in create
as params[:w]
might return nil
. You should instead just pass in w
because that will be each word in the array
you are iterating over and if am not mistaken you want to create a word
object for each word.
def create
split = Word.split_words(params[:word][:word])
@words = split.map do |w|
Word.create(word: w)
end
respond_with(@words)
end
Upvotes: 2
Reputation: 18845
class WordsController < ApplicationController
respond_to :js, :json, :html
def create
@words = params[:word].split.map { |word| Word.create(word) }
respond_with(@words)
end
end
Upvotes: 0