给予
# routes.rb
get ':friend_slug', to: 'friend#show', constraints: FriendConstraint.new
# friend_constraint.rb
def matches?(request)
friend = Friend.find_by(slug: request.params['friend_slug'])
friend.present?
end
由于我已经查找并在路由约束中加入了friend
,如何为控制器保存/传递变量friend
以避免控制器双重查询?
当前,我正在控制器中执行相同的一行Friend.find_by(slug: request.params['friend_slug'])
。
答案 0 :(得分:2)
我找到了解决方案。
创建一个类Current
,在这里你可以设置任何变量。
在app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
attribute :friend
end
在约束中,您可以设置Current.friend
# routes.rb
get ':friend_slug', to: 'friend#show', constraints: FriendConstraint.new
# friend_constraint.rb
def matches?(request)
friend = Friend.find_by(slug: request.params['friend_slug'])
Current.friend = friend ## here I set friend
friend.present?
end
现在,您可以在任何 Current.friend
、controller
、model
或其他地方使用 view
。
答案 1 :(得分:0)
没有干净的方法将变量从约束携带到控制器。
肮脏的方法是直接在request
对象上设置实例变量。
# friend_constraint.rb
def matches?(request)
friend = Friend.find_by(slug: request.params['friend_slug'])
return false if friend.blank?
request.instance_variable_set('@namespace_friend', friend)
end
# friends_controller.rb
...
friend = request.instance_variable_get('@namespace_friend')
...
@namespace_
,因此您永远不会与适当的请求变量发生冲突。
绝对不建议用于生产,但这是一个有趣的练习。
答案 2 :(得分:0)
向 request.params
添加额外的密钥怎么样?像这样:
# friend_constraint.rb
def matches?(request)
friend = Friend.find_by(slug: request.params['friend_slug'])
request.params[:friend] = friend
friend.present?
end