Rails ActiveRecord 找不到正确的用户

Rails ActiveRecord not finding correct user

我正在构建一个应用程序,其中有一个用户 has_one :profile 和一个个人资料 belongs_to :user,但我不明白为什么它要寻找 user_id 而不是 profile_id 当我在个人资料显示页面时。我得到的错误是

Couldn't find User with 'id'=15

  def show
    @user = User.find(params[:id])
    @profile = @user.profile
  end

我有一些与 Subject 模型有关的多态关系。个人资料可以有很多主题,基本上在主题显示页面上,我想 link 注册创建该主题的用户,然后单击以转到该用户的个人资料页面。对不起,如果这很难理解,请找到下面的代码。

users_controller.rb

class UsersController < ApplicationController
  include UserCreateHelper

  skip_before_action :require_login, only: [:new, :create], raise: false

  def show
    @user = User.find(params[:id])
    @profile = @user.profile
  end

  def new
    @user = User.new
  end

  def create
    @user = sign_up(user_params)

    if @user.valid?
      sign_in(@user)
      create_user_profile(current_user)
      redirect_to profile_path(current_user)
    else
      render :new
    end
  end

  private

  def user_params
    params.require(:user).permit(:email, :password)
  end
end

我在这里创建了一个关于用户注册的个人资料实例,并重定向到他们的新个人资料页面以填写他们的详细信息。这一步没问题。

profiles_controller.rb

class ProfilesController < ApplicationController

  def show
    @user = User.find(params[:id])
    @profile = @user.profile
  end

  def update
    if @profile = current_user.profile
      @profile.update(profile_params)
      redirect_to profile_path(current_user)
    end
  end


  private
  def profile_params
    params.require(:profile).permit(:bio, :user_id)
  end
end

上面的配置文件显示方法是造成问题的方法。

views/profiles/show.html.erb

<div>
  <p>Hi <%= @user.email %></p>
  <% if @profile.bio %>
    <hr>
    <p><%= @profile.bio %></p>
  <% else %>
    <p>Fill out the rest of your profile!</p>
    <%= render partial: 'profiles/form', locals: {type: @profile} %>
  <% end %>
</div>
<hr>
<%= render partial: 'subjects/subject', locals: {subjectable: @profile} %>
<%= render partial: 'subjects/form', locals: {subjectable: @profile} %>
<%= render partial: 'locations/location', locals: {locationable: @profile} %>
<%= render partial: 'locations/form', locals: {locationable: @profile} %>

如果在配置文件控制器中显示删除 @user = User.find(params[:id])(我也尝试将其更改为 params[:user_id]),上述多态关联工作正常,但无济于事。正如我所说,删除这一行可以让我很好地添加主题,注册为另一个用户并再次添加主题,在主题 index/all_subjects 页面上列出主题也很好,但是当我尝试 link让创建主题的用户转到他们的个人资料页面失败。

views/subjects/all_subjects.html.erb

<% @all_subjects.each do |subject| %>
  <p><%= subject.title %> | Created by <%= link_to subject.user.email, profile_path(subject.user) %>, <%= time_ago_in_words(subject.created_at) + ' ago' %></p>
<% end %>

我知道这很啰嗦,但如有任何帮助,我们将不胜感激。如果有帮助,我很乐意 link github 回购协议。

schema.rb

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

  create_table "locations", force: :cascade do |t|
    t.integer  "user_id"
    t.string   "locationable_type"
    t.integer  "locationable_id"
    t.string   "suburb"
    t.datetime "created_at",        null: false
    t.datetime "updated_at",        null: false
    t.index ["locationable_type", "locationable_id"], name: "index_locations_on_locationable_type_and_locationable_id"
    t.index ["user_id"], name: "index_locations_on_user_id"
  end

  create_table "profiles", force: :cascade do |t|
    t.integer  "user_id"
    t.text     "bio"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_profiles_on_user_id"
  end

  create_table "subjects", force: :cascade do |t|
    t.integer  "user_id"
    t.string   "title"
    t.text     "description"
    t.string   "subjectable_type"
    t.integer  "subjectable_id"
    t.datetime "created_at",       null: false
    t.datetime "updated_at",       null: false
    t.index ["subjectable_type", "subjectable_id"], name: "index_subjects_on_subjectable_type_and_subjectable_id"
    t.index ["user_id"], name: "index_subjects_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",           null: false
    t.string   "password_digest", null: false
    t.datetime "created_at",      null: false
    t.datetime "updated_at",      null: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end

end

您在滥用 Rails' link 助手。这条线...

profile_path(subject.user) 

需要阅读

profile_path(subject.user.profile) 

profile_path 助手希望它的参数 是个人资料 ,而不是用户。它使用用户记录的 ID,没有匹配的配置文件 ID,因此出现 "user not found" 错误。

另一方面,您不应该在 Profiles 控制器中这样做:

def show
  @user = User.find(params[:id])
  @profile = @user.profile
end

如果有的话,你应该做相反的事情:

def show      
  @profile = Profile.find(params[:id])
  @user = @profile.user
end

在配置文件控制器的上下文中,params[:id] 将是配置文件记录的 ID,而不是用户记录。