我正在构建一个用户has_one :profile
和个人资料belongs_to :user
的应用,但我正在摸索为什么要查找user_id
而不是profile_id
{1}}当我在个人资料显示页面上时。我得到的错误是
Couldn't find User with 'id'=15
def show
@user = User.find(params[:id])
@profile = @user.profile
end
我与Subject模型有一些多态关系。一个配置文件可以有很多主题,基本上在主题显示页面上我想链接创建主题的用户,然后单击转到该用户的配置文件页面。很抱歉,如果难以理解,请找到以下代码。
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
这里我在用户注册时创建个人资料的实例,并重定向到他们的新个人资料页面以填写他们的详细信息。这一步很好。
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
上面的配置文件显示方法是创建问题的方法。
<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]),则上述多态关联工作正常但无效。正如我所说,删除这一行允许我添加主题罚款,注册为另一个用户并再次添加主题,在主题索引/ all_subjects页面列表主题也很好,但当我尝试链接创建的用户如果要访问他们的个人资料页面,则会失败。
<% @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 %>
我知道这很长,但任何帮助都会非常感激。如果有帮助,我很乐意链接github回购。
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
答案 0 :(得分:2)
你误用了Rails的链接助手。这条线......
profile_path(subject.user)
需要阅读
profile_path(subject.user.profile)
profile_path
助手希望其参数成为个人资料,而不是用户。它使用的是用户记录的ID,没有匹配的配置文件ID,因此您的“用户未找到”错误。
另一方面,您不应该在个人资料控制器中执行此操作:
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,而不是用户记录。