You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails关联User与Guest模型:显示创建者问题排查

问题解决:Guest记录关联录入用户显示错误

问题描述

我拥有User.rb和Guest.rb两个模型,应用中由用户负责录入Guest信息。视图内有一个展示全部Guest的表格,期望每一行Guest都显示录入该信息的用户。目前所有Guest旁均显示当前登录用户,请求协助解决该问题。

现有代码

控制器代码(GuestsController)

def new
  @guest = Guest.new
end
 
def create
  @guest = Guest.new(guest_params)
  
  if @guest.save
    redirect_to guests_path
  else
    render 'new'
  end
end
 
def index
  @guests = Guest.all
  @user = current_user
end
 
def show
  @guest = Guest.find(params[:id])
  @user  = current_user
end
 
def edit
  @guest = Guest.find(params[:id])
end
 
def update
  @guest = Guest.find(params[:id])
  if @guest.update(guest_params)
    flash[:success] = "Profile updated"
    redirect_to @guest
  else
    render 'edit'
  end
end
 
def destroy
  Guest.find(params[:id]).destroy
  flash[:success] = "User deleted"
  redirect_to guests_url
end
 
private
def guest_params
  params.require(:guest).permit(:experience,:interaction,:mood,:guest_name,:room_num,:arrival_date,:departure_date,:opportunity_string,:employee,:notes,:opportunity)
end

模型代码

Guest.rb

has_and_belongs_to_many :users
end

User.rb

# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :validatable
      
has_and_belongs_to_many :guests
end

视图代码(guests/index.html.erb)

<style>
body{background-color:white;}
</style>

<h1 class="text-center mt-3">Guests</h1>

<div class="container-fluid" style="overflow-x: auto; mb-3">
  
<table class="table table-bordered  text-center ">
  <thead>
    <tr style="background-color:#CFD2CF;font-size:1.4vw">
      <th>GUEST</th>
      <th>EXPERIENCE</th>
      <th>ROOM</th>
       <th>ARRIVAL</th>
       <th>DEPARTURE</th>
       <th>OPPORTUNITY</th>
       <th>EMPLOYEE</th>
       <th>DEPARTMENT</th>
      
    </tr>
  </thead>

  <tbody>
    <% @guests.each do |guest| %>
      <tr style="background-color:<%=guest.mood%>">
     
        <td> <%= link_to guest.guest_name, "/guests/#{guest.id}" %></td>
        <td><%= guest.experience %></td>
        <td><%= guest.room_num %></td>
        <td><%= guest.arrival_date %></td>
        <td><%= guest.departure_date %></td>
        <td ><%= @user.current_user%></td>
        <td><%=  %></td>
        <td><%= guest.interaction %></td>
       </tr>
    <% end %>
  </tbody>
</table>
</div>

Schema代码

create_table "guests", force: :cascade do |t|
  t.string "experience"
  t.string "interaction"
  t.string "mood"
  t.string "guest_name"
  t.string "room_num"
  t.string "arrival_date"
  t.string "departure_date"
  t.string "opportunity_string"
  t.string "employee"
  t.string "notes"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.integer "user_id", null: false
  t.index ["user_id"], name: "index_guests_on_user_id"
end

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.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.boolean "superadmin_role", default: false
  t.boolean "supervisor_role", default: false
  t.boolean "user_role", default: true
  t.string "name"
  t.index ["email"], name: "index_users_on_email", unique: true
  t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

add_foreign_key "guests", "users"

解决方案

1. 修正模型关联关系

从Schema可以看到,guests表有user_id外键且设置为非空,说明一个Guest只能属于一个User,一个User可以创建多个Guest,是一对多关系,而非当前的多对多(has_and_belongs_to_many)。修改模型:

Guest.rb

belongs_to :user
end

User.rb

# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :validatable
      
has_many :guests
end

2. 确保新建Guest时关联当前用户

修改create方法,将当前登录用户绑定到新建的Guest上,否则user_id字段无法填充(Schema要求非空):

def create
  # 用current_user关联新建Guest,自动设置user_id
  @guest = current_user.guests.new(guest_params)
  
  if @guest.save
    redirect_to guests_path
  else
    render 'new'
  end
end

3. 修正视图显示逻辑

视图中错误地使用了@user.current_user(而且@user本身就是current_user),应该通过guest.user获取该Guest的录入用户,然后显示其名称或邮箱:

修改视图中对应行:

<td ><%= guest.user.name %></td>

如果想显示邮箱则改为:

<td ><%= guest.user.email %></td>

同时可以删除index方法中的@user = current_user,因为视图不再需要这个变量。

4. 可选:预加载关联优化性能

为了避免N+1查询问题,在index方法中预加载user关联:

def index
  @guests = Guest.all.includes(:user)
end

验证效果

完成以上修改后,重新启动服务器,录入新的Guest记录,表格中每行Guest的“EMPLOYEE”列会显示录入该记录的用户信息,而非当前登录用户。

内容的提问来源于stack exchange,提问作者Ari Ticas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:10:31