问题
I am getting the following error when I try to submit a form (the form shows up when 1 user wants to message another user)
NoMethodError in MessagesController#create
undefined method `stringify_keys' for "":String
Rails.root: /Users/fkhalid2008/loand
Application Trace | Framework Trace | Full Trace
app/controllers/messages_controller.rb:31:in `new'
app/controllers/messages_controller.rb:31:in `create'
Here is the relevant code from Messages Controller:
def new
@message = Message.new
if params[:reply_to]
@reply_to = @user.received_messages.find(params[:reply_to])
unless @reply_to.nil?
@message.to = @reply_to.sender.login
@message.subject = "Re: #{@reply_to.subject}"
@message.body = "\n\n*Original message*\n\n #{@reply_to.body}"
end
end
end
def create
@message = Message.new(params[:message])
@message.sender = @user
@message.recipient = User.find_by_login(params[:message][:to])
if @message.save
flash[:notice] = "Message sent"
redirect_to user_messages_path(@user)
else
render :action => :new
end
end
How do I fix this?
More supporting code is below:
MESSAGES>NEW VIEW (This is where Form is being created)
<%= form_for @message, :url => messages_path(:user_id => @user) do |f| %>
<br>
<br />
<br />
<div class="field">
<label>Name</label>
<input type="text" name="name" id="contact_name" class="required" />
</div>
<div class="field">
<label>Email</label>
<input type="text" name="email" id="contact_email" class="required" />
</div>
<div class="field">
<label>Subject</label>
<input type="text" name="subject" id="contact_subject" class="required" />
</div>
<div class="field">
<label>Message</label>
<textarea name="message" rows="8" cols="25" id="contact_message" class="required max_len", max_length=1000 /></textarea>
</div>
<div class="btn">
<%= submit_tag 'Send Message' %>
</div>
<% end %>
MESSAGE MODEL
class Message < ActiveRecord::Base
is_private_message
attr_accessor :to
end
USER MODEL
class User < ActiveRecord::Base
has_many :posts
has_one :profile
has_private_messages
attr_accessible :email
validates_presence_of :email
validates_uniqueness_of :email, :message =>"Hmm, that email's already taken"
validates_format_of :email, :with => /^([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})$/i, :message => "Hi! Please use a valid email"
end
POSTS>INDEX VIEW (This is where Form is being linked to)
<table class="table table-striped">
<tbody>
<% @posts.each do |post| %>
<tr>
<td>I am a <%= post.title %> getting married in <%= post.job %> in <%= post.location %>, and looking for a <%= post.salary %>. My budget is <%= post.salary %>.</td>
<td> <button class="btn" data-toggle="button" onClick="javascript:location.href = '/messages/new';" />Contact</button></td>
<td><%= time_ago_in_words(post.created_at) %> ago.</td>
<!--/.
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
-->
</tr>
<% end %>
</tbody>
</table>
DEVELOPMENT LOG
Started POST "/messages" for 127.0.0.1 at Sun Apr 22 01:54:57 +0500 2012
Processing by MessagesController#create as HTML
Parameters: {"name"=>"faisal", "commit"=>"Send Message", "authenticity_token"=>"Qyww9hP6jLmqpQ+ua21FAk9vePju8Gpq39Gpaflf3wE=", "utf8"=>"\342\234\223", "subject"=>"testing", "message"=>"hello", "email"=>"fas@fas.com"}
User Load (0.1ms) SELECT "users".* FROM "users" LIMIT 1
Completed 500 Internal Server Error in 17ms
NoMethodError (undefined method `stringify_keys' for "hello":String):
app/controllers/messages_controller.rb:31:in `new'
app/controllers/messages_controller.rb:31:in `create'
回答1:
Now I see. You've built you form in a completely inconsistent way:
<%= form_for @message, :url => messages_path(:user_id => @user) do |f| %>
and then:
<input type="text" name="name" id="contact_name" class="required" />
what leads you to the situation where this text field has nothing to do with the message. Do you see any mention of message
within the last tag?
Solution is simple: use helpers.
Instead of your markup:
<label>Name</label>
<input type="text" name="name" id="contact_name" class="required" />
use helpers:
<%= f.label :name %>
<%= f.text_field :name %>
And your fields will become properly named (like message[name]
) and you'll get in your controller proper params[:message]
. Of course, you can make it manually but practice shows that it isn't the best decision.
Repeat this step for every of your other fields.
回答2:
What I would guess is happening is params[:message]
isn't a hash as Rails expects it to be. You should definitely follow jdoe's advice and post your form code b/c I would suspect that it's not right.
Additionally, you can see what data you're posting to your app in the development log. Post that as well. It'll look something like:
Started POST "/message" for 127.0.0.1 at 2012-04-19 16:49:22 -0400
Processing by MessagesController#create as HTML
Parameters: {"key"=>"value"}
The "Parameters" is what you want to be looking at.
回答3:
When you call Message.new(params[:message])
, params[:message]
needs to be a hash with the message attributes. In your form, and consequently in your post as shown by the logfile, params[:message]
is a string.
Change
<textarea name="message" rows="8" cols="25" id="contact_message" class="required max_len", max_length=1000 /></textarea>
to
<textarea name="message[message]" rows="8" cols="25" id="contact_message" class="required max_len", max_length=1000 /></textarea>
or better
<%= f.text_area :message, :rows => 9, :cols => 25, :class => "required max_len", :max_length => 1000 %>
But - there are a ton of other errors in your form that you will encounter soon - for example, there's no message[to]
parameter, yet you're expecting one in your controller. I suggest reading up on a few Rails tutorials such as this one.
来源:https://stackoverflow.com/questions/10262576/undefined-method-stringify-keys-in-messages-controller