What i'm trying to do is have a constraint on my routes to make sure the object is a "widget " or a "sprocket" or an anything before routing to it , and eventually validating against it
After taking a look at http://guides.rubyonrails.org/routing.html#advanced-constraints, I have the following on my routes.rb
class WidgetssConstraint
def initialize
@widgets = Widget.all
end
def matches?(request)
@widgets.include?(request.widget_slug)
end
end
FunParts::Application.routes.draw do
namespace 'admin' do
resources :widgets
resources :sprockets
root 'widgets#index'
end
get "*widget_slug" => "widgets#show" , :constraints => WidgetsConstraint.new
end
and my widgets controller looks like this
class WidgetsController < ApplicationController
layout 'public'
def show
@widget= Widget.where(slug: params[:widget_slug]).first
if @widget.present?
render :show
else
render :file => "#{Rails.root}/public/404", :layout => false, status: 404
end
end
end
I get the error below
undefined method `widget_slug' for ActionDispatch::Request:0x56ea700
Extracted source (around line #7):
def matches?(request)
@trucks.include?(request.widget_slug)
end
end
Request
Parameters:
{"widget_slug"=>"ultra/lifter"}
The problem is this line:
@widgets.include?(request.widget_slug)
You're calling widget_slug
on the request object, which knows nothing about widgets. Here are the docs for Request: http://api.rubyonrails.org/classes/ActionDispatch/Request.html
I'd suggest moving this functionality to the widget controller. It's simple enough to do the validation in your show action rather than create a Constraint, especially one that fetches all widgets on every request.