Неопределенный метод stringify_keys в контроллере сообщений

Я получаю следующую ошибку, когда пытаюсь отправить форму (форма появляется, когда 1 пользователь хочет отправить сообщение другому пользователю)

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'

Вот соответствующий код из контроллера сообщений:

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

Как я могу это исправить?

Ниже приведен дополнительный вспомогательный код:

СООБЩЕНИЯ>НОВОЕ ПРЕДСТАВЛЕНИЕ (здесь создается форма)

<%= 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 %>

МОДЕЛЬ СООБЩЕНИЯ

class Message < ActiveRecord::Base

is_private_message

attr_accessor :to

end

ПОЛЬЗОВАТЕЛЬСКАЯ МОДЕЛЬ

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

Публикации>INDEX VIEW (здесь ссылка на форму)

<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>

ЖУРНАЛ РАЗРАБОТКИ

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"=>"[email protected]"}
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'

person hikmatyar    schedule 21.04.2012    source источник
comment
Покажите нам форму, в которой вы создаете свое сообщение. И @user появился ни с того ни с сего...   -  person jdoe    schedule 22.04.2012
comment
@jdoe, пожалуйста, смотрите выше, я добавил форму и другой вспомогательный код   -  person hikmatyar    schedule 22.04.2012
comment
Вы уверены, что разместили верные данные? Лог содержит совсем другой набор параметров. Может это неправильная форма? И как ваша форма смогла отобразить себя, если вы пытались вывести ее без знака равенства: <% form_for?   -  person jdoe    schedule 22.04.2012
comment
@jdoe приношу свои извинения, см. обновленный код выше.   -  person hikmatyar    schedule 22.04.2012


Ответы (3)


Теперь я вижу. Вы построили свою форму совершенно непоследовательным образом:

<%= form_for @message, :url => messages_path(:user_id => @user) do |f| %>

а потом:

<input type="text" name="name" id="contact_name" class="required" />

что приводит вас к ситуации, когда это текстовое поле не имеет ничего общего с сообщением. Вы видите упоминание message в последнем теге?

Решение простое: используйте помощников.

Вместо вашей разметки:

<label>Name</label>
<input type="text" name="name" id="contact_name" class="required" />

использовать помощники:

<%= f.label :name %>
<%= f.text_field :name %>

И ваши поля будут называться правильно (например, message[name]), и вы получите правильный контроллер params[:message]. Конечно, можно сделать это вручную, но практика показывает, что это не лучшее решение.

Повторите этот шаг для каждого из ваших других полей.

person jdoe    schedule 21.04.2012
comment
спасибо!!! очень ценю это, и это решило проблему. (хотя, как указал Тило в своем ответе, теперь есть некоторые другие ошибки, которые мне нужно исправить) - person hikmatyar; 22.04.2012

Я предполагаю, что происходит то, что params[:message] не является хэшем, как ожидает Rails. Вы обязательно должны последовать совету jdoe и опубликовать свой код формы, потому что я подозреваю, что это неправильно.

Кроме того, вы можете увидеть, какие данные вы публикуете в своем приложении, в журнале разработки. Опубликуйте это также. Это будет выглядеть примерно так:

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"}

«Параметры» - это то, на что вы хотите смотреть.

person pcg79    schedule 21.04.2012
comment
Я добавил журнал разработки и код формы выше .. пожалуйста, дайте мне знать, если вы видите, где ошибка .. спасибо! - person hikmatyar; 22.04.2012

Когда вы вызываете Message.new(params[:message]), params[:message] должен быть хешем с атрибутами сообщения. В вашей форме и, следовательно, в вашем сообщении, как показано в файле журнала, params[:message] является строкой.

Сдача

<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>

или лучше

<%= f.text_area :message, :rows => 9, :cols => 25, :class => "required max_len", :max_length => 1000 %>

Но - в вашей форме есть масса других ошибок, с которыми вы скоро столкнетесь - например, нет параметра message[to], но вы ожидаете его в своем контроллере. Я предлагаю прочитать несколько руководств по Rails, таких как этот.

person Thilo    schedule 21.04.2012
comment
спасибо!! очень ценится. я получил 2 правильных ответа в этом случае (ваш и jdoe), поэтому, чтобы быть честным, я выбрал тот, который был опубликован первым.. т.е. jdoe... извините за это! - person hikmatyar; 22.04.2012