1

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.

4
  • Can you post your form. Commented Jun 10, 2014 at 17:16
  • 1
    Im thinking the match method isn't available for the ActiveSupport::HashWithIndifferentAccess object, can you convert the word object to a standard ruby hash object before the conditional? api.rubyonrails.org/classes/ActiveSupport/… Commented Jun 10, 2014 at 17:23
  • Yeah just tried it in console, you could do something like w = word.to_hash, if w.match... Commented Jun 10, 2014 at 17:41
  • Still getting the error.. I've also tried putting the conditional directly in the controller action Commented Jun 10, 2014 at 18:01

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

2 Comments

When using the query "stack", This causes a NoMethodError (undefined method `stringify_keys' for "stack":String):
On which line Kyle.Belanger? Could you also tell me what params[word][word] returns. For this {"word"=>"stack, overflow"} I was expecting it to return "stack, overflow".
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

2 Comments

This answer was flagged for deletion but I'm not going to delete it. However, a few words around your solution will massively improve the answer and also help the OP understand how this solves their problem.
I agree with @RoboticCat. However, this still returns a HashWithIndifferentAccess error regardless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.