顶级路由下多个控制器的路由约束

时间:2017-06-28 09:38:15

标签: ruby-on-rails devise routes constraints ruby-on-rails-5

我正在寻找关于良好实践理念和使用顶级路线的技术实践的一些反馈,该路线根据条件路由到多个模型。

我需要有一个顶级路线domain.com/:id,路由到:公司用户

条件/标识符是用户在网址中具有@的条件,例如domain.com/@theminijohn

我目前的路线如下:

devise_for :users, path: '',
  path_names: {
    sign_up: '',
    registration: 'signup',
    sign_in: 'login',
    password: 'password',
    confirmation: 'verification'
  },
  controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
    omniauth_callbacks: 'users/omniauth_callbacks',
    passwords: 'users/passwords'
  }

resources :users, path: '', only: [:show] do
  member do
    get 'reviews', to: 'users#reviews', as: :reviews
    get :following, :followers
    post :follow, to: 'users#follow_user'
    post :unfollow, to: 'users#unfollow_user'
  end
end

resources :companies, path: '', only: [:show], as: :company do
  resources :products, path: '', only: [:show], as: :product
end

此外,@符号仅用于网址,即属性中不存在。

我该怎么做?

编辑:这就是我的位置:

:users资源

的路由调用的约束
module Constraints
  class UserProfile
    def matches?(request)
      if request.path.include?('@')
        slug = request.path.delete('/@')
        User.where(slug: slug).exists?
      end
    end
  end
end

在控制器中我将find方法修补为:

def set_user
  @user = User.includes(:reviews).find(params[:id].delete('@'))
end

1 个答案:

答案 0 :(得分:0)

我最终如何解决这个问题:

1)在@ slug

中加入friendly_id

要做到这一点,我必须修补normalize函数,该函数在调用.parameterize时将其删除

# overwrite normalize function because it's stripping 
# out '@' when calling .parameterize
def normalize_friendly_id(value)
  "@" + value.to_s.parameterize
end

2)重新生成所有slu

有各种各样的方法,我去删除slug并再次生成它。

User.each do |u|
  u.update_attribute(:slug, nil)
end

User.find_each(&:save)

请记住should_generate_new_friendly_id?&如果你覆盖它。

3)路由约束

我将用户路线包裹在一个约束中:

constraints(Constraints::UserProfile.new) do
  resources :users,
  ....
end

看起来像这样:

module Constraints
  class UserProfile
    def matches?(request)
      if request.path.match? /\/@(.*)/
        slug = request.path.split('/')[1]
        User.where(slug: slug).exists?
      end
    end
  end
end

瞧。