【问题标题】:ActiveRecord::RecordNotFound in ConversationsController#index -- Couldn't find User with 'id'=ConversationsController#index 中的 ActiveRecord::RecordNotFound -- 找不到具有 'id'= 的用户
【发布时间】:2015-03-10 17:09:02
【问题描述】:

在我的 Ruby on Rails 应用程序中尝试访问 /conversations URL 时收到以下错误:

ActiveRecord::RecordNotFound in ConversationsController#index

Couldn't find User with 'id'=

Extracted source (around line #154):
152    record = s.execute([id], self, connection).first
153    unless record
154      raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
155    end
156    record
157  rescue RangeError

Rails.root: /home/ubuntu/workspace

app/controllers/conversations_controller.rb:25:in `correct_user'

此错误表示什么?我已经在 routes.rb 文件中定义了资源:

resources :conversations, only: [:index, :show, :destroy]

而 _header.html.erb 中用于访问 /conversations URL 的链接是:

<li>
  <%= link_to conversations_path do %>
    <span class="glyphicon glyphicon-envelope"></span>&nbsp;Messages
  <% end %>
</li>

附加信息:

-对话控制器

class ConversationsController < ApplicationController
  before_action :logged_in_user, only: [:index, :show, :destroy]
  before_action :correct_user, only: [:index, :show, :destroy]
  before_action :get_mailbox
  before_action :get_conversation, except: [:index]

  def show
  end

  def index
    @conversations = @mailbox.inbox.paginate(page: params[:page], per_page: 10)
  end

  private

  def get_mailbox
    @mailbox ||= current_user.mailbox
  end

  def get_conversation
    @conversation ||= @mailbox.conversations.find(params[:id])
  end

  def correct_user
    @user = User.find(params[:id])
    redirect_to(root_url) unless current_user?(@user)
  end
end

-用户模型

class User < ActiveRecord::Base
  acts_as_messageable
  has_many :listings, dependent: :destroy
  attr_accessor :remember_token, :activation_token, :reset_token
  before_save   :downcase_email
  before_create :create_activation_digest
  validates :first_name,  presence: true, length: { maximum: 25 }
  validates :last_name, presence: true, length: { maximum: 50 }
  validates :username, presence: true, uniqueness: true, length: {maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                                    format: { with: VALID_EMAIL_REGEX },
                                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, length: { minimum: 6 }, allow_blank: true


  class << self
    # Returns the hash digest of the given string.
    def digest(string)
      cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                                                                BCrypt::Engine.cost
      BCrypt::Password.create(string, cost: cost)
    end

    # Returns a random token.
    def new_token
      SecureRandom.urlsafe_base64
    end
  end

# Remembers a user in the database for use in persistent sessions.
def remember
  self.remember_token = User.new_token
  update_attribute(:remember_digest, User.digest(remember_token))
end

# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
  digest = send("#{attribute}_digest")
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

# Forgets a user.
def forget
  update_attribute(:remember_digest, nil)
end

# Activates an account.
def activate
  update_attribute(:activated,  true)
  update_attribute(:activated_at, Time.zone.now)
end

# Sends activation email.
def send_activation_email
  UserMailer.account_activation(self).deliver_now
end

# Sets the password reset attributes.
def create_reset_digest
  self.reset_token = User.new_token
  update_attribute(:reset_digest, User.digest(reset_token))
  update_attribute(:reset_sent_at, Time.zone.now)
end

# Sends password reset email.
def send_password_reset_email
  UserMailer.password_reset(self).deliver_now
end

# Returns true if a password reset has expired.
def password_reset_expired?
  reset_sent_at < 2.hours.ago
end


private

  # Converts email to all lower-case.
  def downcase_email
    self.email = email.downcase
  end

  # Creates and assigns the activation token and digest.
  def create_activation_digest
    self.activation_token  = User.new_token
    self.activation_digest = User.digest(activation_token)
  end
end

【问题讨论】:

  • 你有一个错字def correct_user,应该是current_user

标签: ruby-on-rails ruby activerecord controller


【解决方案1】:

如果您的网址是/conversations,而您只显示current_user.mailbox,那么您不需要导致问题的before_action :correct_user,因此这里最快的解决方案是将其删除。只有当可以看到其他人的对话 (@user.mailbox),其 url 包含 :user_id - 所以 /users/1/conversations, /users/2/conversations 时,它才会有用(并且工作正常)。 url 中没有用户 id,@user = User.find(params[:user_id]) 正在搜索没有 id 的用户 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    相关资源
    最近更新 更多