使用嵌套路线创建家园

Creating homes using nested routes

首先这是我的全部代码

  #models/user.rb
  class User < ApplicationRecord
  has_many :trips
  has_many :homes, through: :trips
  has_secure_password
  accepts_nested_attributes_for :trips
  accepts_nested_attributes_for :homes
  validates :name, presence: true
  validates :email, presence: true
  validates :email, uniqueness: true
  validates :password, presence: true
  validates :password, confirmation: { case_sensitive: true }
end
#home.rb
class Home < ApplicationRecord
  has_many :trips
  has_many :users, through: :trips
  validates :address, presence: true
end
class HomesController < ApplicationController

  def show
    @home = Home.find(params[:id])
  end
  
  def new

    if params[:user_id]
      @user = User.find_by(id: params[:user_id])
      @home = @user.homes.build
    end
  end

  def create
    @user = User.find_by(id: params[:user_id])
    binding.pry
    @home = Home.new
  end

  private
  def home_params
    params.require(:home).permit(:address, :user_id)
  end
end

我正在尝试做这样的事情,以便创建的家庭与创建它的用户相关联。

  def create
    @user = User.find_by(id: params[:user_id])
    @home = Home.new(home_params)
    if @home.save
      @user.homes << @home
    else
      render :new
    end
  end

问题是 :user_id 没有被传递到参数中。所以 @user 结果为 nil。我找不到原因。这个例子有意义吗?我是否尝试正确设置关联?帮助或任何见解将不胜感激。提前致谢。

您作为当前用户通常创建资源的方式是使用诸如 Devise 之类的身份验证,而不是通过嵌套资源。相反,您通过身份验证系统在控制器中获取当前用户并从中构建资源:

resources :homes

class HomesController < ApplicationController

  ...

  # GET /homes/new
  def new
    @home = current_user.homes.new
  end

  # POST /homes
  def create
    @home = current_user.homes.new(home_parameters)
    if @home.save
      redirect_to @home
    else
      render :new
    end
  end

  ...
end

这会在处理 API 时从会话或类似访问令牌的模型(在本例中为 Trip 连接模型)设置 user_id

当您以特定用户身份创建资源时,您不想嵌套资源的原因是传递另一个用户 ID 以以另一个用户身份创建资源是微不足道的。会话 cookie 是加密的,因此更难被篡改,身份验证令牌也是如此。

通过使用 if params[:user_id]User.find_by(id: params[:user_id]) 你真的只是在给自己潜在的零错误并搬起石头砸自己的脚。如果操作需要用户登录,请使用 before_action 回调以确保他们已通过身份验证并引发错误并保释(将用户重定向到登录)。这就是像 Devise、Knock 和 Sorcery 这样的身份验证宝石如何处理它。