使用嵌套路线创建家园
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 这样的身份验证宝石如何处理它。
首先这是我的全部代码
#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 这样的身份验证宝石如何处理它。