新到轨道。在关于多态关联的教程之后,我遇到了这个来设置创建和销毁@client。
@client = Client.find(params[:client_id] || params[:id])
我通常只习惯于你只能找到@client = Client.find(params[:id])
那么,在有两个参数的情况下,这是如何工作的呢?如何 ||工作?
FavoriteClientsController.rb:
class FavoriteClientsController < ApplicationController
def create
@client = Client.find(params[:client_id] || params[:id])
if Favorite.create(favorited: @client, user: current_user)
redirect_to @client, notice: 'Leverandøren er tilføjet til favoritter'
else
redirect_to @client, alert: 'Noget gik galt...*sad panda*'
end
end
def destroy
@client = Client.find(params[:client_id] || params[:id])
Favorite.where(favorited_id: @client.id, user_id: current_user.id).first.destroy
redirect_to @client, notice: 'Leverandøren er nu fjernet fra favoritter'
end
end
控制器的完整代码,模型可以在这里看到
使用导轨 5
表达式:params[:client_id] || params[:id]
与
if params[:client_id]
params[:client_id]
else
params[:id]
end
这是一种非常糟糕的方法。
为多态子项执行控制器的一个非常可扩展且干净的模式是使用继承:
class FavoritesController < ApplicationController
def create
@favorite = @parent.favorites.new(user: current_user)
if @favorite.save
redirect_to @parent, notice: 'Leverandøren er tilføjet til favoritter'
else
redirect_to @parent, alert: 'Noget gik galt...*sad panda*'
end
end
def destroy
@favorite = @parent.favorites.find_by(user: current_user)
redirect_to @parent, notice: 'Leverandøren er nu fjernet fra favoritter'
end
private
def set_parent
parent_class.includes(:favorites).find(param_key)
end
def parent_class
# this will look up Parent if the controller is Parents::FavoritesController
self.class.name.deconstantize.singularize.constantify
end
def param_key
"#{ parent_class.naming.param_key }_id"
end
end
然后我们定义子类:
# app/controllers/clients/favorites_controller.rb
module Clients
class FavoritesController < ::FavoritesController; end
end
# just an example
# app/controllers/posts/favorites_controller.rb
module Posts
class FavoritesController < ::FavoritesController; end
end
然后,您可以使用以下方法创建路由:
Rails.application.routes.draw do
# this is just a routing helper that proxies resources
def favoritable_resources(*names, **kwargs)
[*names].flatten.each do |name|
resources(name, kwargs) do
scope(module: name) do
resource :favorite, only: [:create, :destroy]
end
yield if block_given?
end
end
end
favoritable_resources :clients, :posts
end
最终结果是基于 OOP 而不是"聪明"代码的可自定义模式。
教你做
Client.find(params[:client_id] || params[:id])
是一个超级骗子糟糕的教程:)我强烈建议您切换到另一个。
回到主题:这是逻辑的 OR:如果第一个表达式既不是nil
也不是false
,则返回它,否则返回第二个表达式。
那件事只是试图通过client_id
请求参数中是否有客户端来查找客户端。如果没有,它试图通过id
找到客户。
然而,这种做法会让你痛苦多于利润。