未定义的方法`sender_id ='为零:NilClass

时间:2016-03-16 19:18:38

标签: ruby-on-rails

目前我正在使用Rails创建类似应用程序的应用程序。我收到错误:

  

未定义的方法`sender_id ='为零:NilClass

当我尝试提交新的邮件表单时,我真的不知道我在哪里弄错了。此外,我不确定我的messages_controller中创建操作的逻辑,基本上我只是希望发件人通过同时选择一个或多个收件人向他们的朋友列表中的人发送消息(当然,收件人必须是在他们的朋友列表中,我已经完成了这个功能)。但是,因为我仍然无法弄清楚如何将params recipient_id传递给表单(我使用简单的形式gem并设计gem),所以我在创建操作中硬编码了recipient_id。所以,欢迎所有建议/建议。 这是我的文件:

messages_controller.rb

class MessagesController < ApplicationController
  def new
    @message = Message.new
  end

  def create
    @message.sender_id = current_user
    @message.recipient_id = current_user.friendships.friend_id
    @message = Message.new(message_params)
    if @message.save?
      flash[:success] = 'Message sent successfully'
      redirect_to welcome_profile_path
    else
      render 'new'
    end
  end

  private

    def message_params
      params.require(:message).permit(:body, :sender_id, :recipient_id, :user_id)
    end
end

讯息/ new.html.erb

<h1>Create New Message</h1>

<%= simple_form_for @message do |f| %>
  <%= f.input :body %>
  <%#= f.association :user, :as => :hidden, :input_html => { :value => current_user.id }, :include_blank => false %>
  <%= f.button :submit, "Send Message", class: "btn btn-secondary" %>
<% end %>

message.rb

class Message < ActiveRecord::Base
  belongs_to :user, foreign_key: :recipient_id

  belongs_to :sender, :foreign_key => :sender_id, class_name: 'User'
  belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'User'

  validates_presence_of :body

end

user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  validates :username,
  :presence => true,
  :uniqueness => {
    :case_sensitive => false
  }

  validate :validate_username

  def validate_username
    if User.where(email: username).exists?
      errors.add(:username, :invalid)
    end
  end

  has_many :friendships
  has_many :friends, :through => :friendships
  has_many :inverse_friendships,  :class_name => "Friendship", :foreign_key => "friend_id"
  has_many :inverse_friends, :through => :inverse_friendships, :source => :user

  has_many :messages, dependent: :destroy

end

schema.rb

ActiveRecord::Schema.define(version: 20160316170009) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "friendships", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "friend_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "messages", force: :cascade do |t|
    t.text     "body"
    t.boolean  "read"
    t.integer  "sender_id"
    t.integer  "recipient_id"
    t.integer  "user_id"
    t.datetime "created_at",   null: false
    t.datetime "updated_at",   null: false
  end

  add_index "messages", ["user_id"], name: "index_messages_on_user_id", using: :btree

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "username"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
  add_index "users", ["username"], name: "index_users_on_username", unique: true, using: :btree

  add_foreign_key "messages", "users"
end

1 个答案:

答案 0 :(得分:1)

该错误是因为您在@message操作中设置@message.sender_id之前未定义create。在设置@message = Message.new(message_params)之前,将create移至@message.sender_id操作的顶部,如下所示:

class MessagesController < ApplicationController
  ...

  def create
    @message = Message.new(message_params)

    @message.sender_id = current_user
    @message.recipient_id = current_user.friendships.friend_id
    if @message.save?
      flash[:success] = 'Message sent successfully'
      redirect_to welcome_profile_path
    else
      render 'new'
    end
  end

  private

    def message_params
      params.require(:message).permit(:body, :sender_id, :recipient_id, :user_id)
    end
end

问题的第二部分 - current_user在您的控制器中可用,因此您不需要隐藏字段。您可以按照目前的@message.sender_id = current_user.id操作拨打create。接下来,要设置@message.recipient_id,您可以按如下方式更新new.html.erb

# new.html.erb
<h1>Create New Message</h1>

<%= simple_form_for @message do |f| %>
  <%= f.input :body %>

  <%# Updated the following line. You could chose to create a hidden field here, or however you wish to implement this in your view as long as you specify `recipient` as the association or `recipient_id` as the field. %>
  <%= f.association :recipient, :include_blank => false %>

  <%= f.button :submit, "Send Message", class: "btn btn-secondary" %>
<% end %>

通过上述设置,您的create操作可以更新为:

 # app/controllers/messages_controller.rb

 def create
    @message = Message.new(message_params)
    @message.sender_id = current_user

    if @message.save?
      flash[:success] = 'Message sent successfully'
      redirect_to welcome_profile_path
    else
      render 'new'
    end
  end