Rails 高级约束将变量从路由传递到控制器
Rails Advanced Constraint pass variable from Routes to Controller
给出
# 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
,我如何 save/pass 我的控制器变量 friend
以避免重复查找?
目前,我正在控制器中执行完全相同的行,Friend.find_by(slug: request.params['friend_slug'])
。
没有干净的方法可以将变量从约束传送到控制器。
肮脏的方法是直接在 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_
这样您就不会与正确的请求变量发生冲突。
绝对不推荐用于生产,但这是一个有趣的练习。
我找到了解决办法。
创建一个classCurrent
,这里可以设置任意变量。
在app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
attribute :friend
end
在constraint中,可以设置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
现在,您可以在任何 controller
、model
、view
或其他地方使用 Current.friend
。
如何向 request.params
添加额外的密钥?像这样:
# friend_constraint.rb
def matches?(request)
friend = Friend.find_by(slug: request.params['friend_slug'])
request.params[:friend] = friend
friend.present?
end
给出
# 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
,我如何 save/pass 我的控制器变量 friend
以避免重复查找?
目前,我正在控制器中执行完全相同的行,Friend.find_by(slug: request.params['friend_slug'])
。
没有干净的方法可以将变量从约束传送到控制器。
肮脏的方法是直接在 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_
这样您就不会与正确的请求变量发生冲突。
绝对不推荐用于生产,但这是一个有趣的练习。
我找到了解决办法。
创建一个classCurrent
,这里可以设置任意变量。
在app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
attribute :friend
end
在constraint中,可以设置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
现在,您可以在任何 controller
、model
、view
或其他地方使用 Current.friend
。
如何向 request.params
添加额外的密钥?像这样:
# friend_constraint.rb
def matches?(request)
friend = Friend.find_by(slug: request.params['friend_slug'])
request.params[:friend] = friend
friend.present?
end