ruby-on-rails Ruby on Rails将用户与另一个模型文本字段关联

bogh5gae  于 2022-11-19  发布在  Ruby
关注(0)|答案(1)|浏览(157)

你好,我有2个模型User.rb和Guest.rb.
在我的应用程序中,用户负责输入客人信息。我在视图中有一个表,它将显示所有客人。我希望每个客人行都显示输入了他们信息的用户。我在我的控制器方法中正确设置current_user方法时遇到了一些麻烦。目前,我正在获取current_usera并在每个客人旁边输入它。提前非常感谢。
控制器:

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

  
  def guest_params
      params.require(:guest).permit(:experience,:interaction,:mood,:guest_name,:room_num,:arrival_date,:departure_date,:opportunity_string,:employee,:notes,:opportunity)
 end
end

型号:
第一次
浏览次数:

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>

结构描述:

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"
end
woobm2wo

woobm2wo1#

以下几点会有所帮助:

设计和current_user

Devise会为您处理current_user,因此您应该能够在控制器和视图中调用current_user
@user.current_user不是一个方法,除非您已经在User模型中创建了一个方法,我不建议您这样做。

不要将@usercurrent_user混合

可以设置@user = current_user,但我认为这是一个不好的做法,因为它会很快变得混乱
@user应该绑定到模型User,并表示与current_user交互的用户。
例如,像/users/1/edit这样的URL应该设置为@user = User.find(1)
current_user可能是正在编辑@user对象的其他人。

HABTM关联

给定一个分配的@user,您可以调用@user.guests来获取与该用户关联的所有guest虚拟机。
例如,对于创建以下URL的路由:/users/1/guests,则您的控制器可能会有如下内容:

# users_controller.rb

class UsersController < ApplicationController

...

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

end

反之亦然,对于guests/1/users这样的路径,你可以调用@guest.users
可是......

您真的想要HABTM吗?

如果一个User可以创建多个Guests,但是一个Guest从未与 manyUsers关联,那么这就不是一个真正的“has and belongs to many”关系,您可能只需要一个简单的has_many belongs_to
当我考虑我的关系时,我经常重温this article作为复习。
您的模式在guest模型上有一个user_id,这向我表明您希望能够说:“一个用户有_多个访客。访客属于_一个用户。”
但你不会真的说“一个客人可以属于_许多用户”

代码修复

我的视图中有一个表,它将显示所有访客。
对于所有访客,这将是URL /guests,它应Map到GuestsController#index

# guests_controller.rb

class GuestsController < ApplicationController

...

  def index
   @guests = Guest.all # or some scope like Guest.active
  end
...
end

对于与给予用户相关的访客,这将是URL /users/:id/guests,其应Map到UsersController#guests

# users_controller.rb

class UsersController < ApplicationController
  before_action :set_user, only: %i[show edit update guests]
...
  def guests
   @user.guests
   ...
  end
...

  private

  # this method sets @user for all views defined in the `:only` hash of the `before_action` callback.
  def set_user
    @user = User.find(params[:id]
  end

我希望每个访客行都显示已输入其信息的用户。
由于在Guest上有一个user_id字段,如果切换到has_manybelongs_to关系,则只需调用用户:

<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 ><%= guest.user%></td> <!-- guest.user instead of @user.current_user -->
      <td></td>
      <td><%= guest.interaction %></td>
     </tr>
  <% end %>
</tbody>

额外学分:使用“包括”预加载关联

此外,作为一个专业提示,调用guest.user可能会很慢,因为每个guest记录都需要调用User表。
Rails为这种情况提供了快速加载。
@guests = Guest.all更改为@guest = Guest.includes(:user).all,Rails将处理其余部分。

相关问题