【问题标题】:Routing constraints for multiple controllers under top level route顶级路由下多个控制器的路由约束
【发布时间】:2017-06-28 09:38:14
【问题描述】:

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

我需要有一个顶级路由 domain.com/:id 路由到:CompanyUser

条件/标识符是用户在 url 中有 @,例如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

此外,@ 符号只会在 url 中使用,也就是在属性中不存在。

我该怎么办?

编辑:这是我的位置:

: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

【问题讨论】:

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


    【解决方案1】:

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

    1) 在friendly_id slug 中包含@

    为此,我必须修补 normalize 函数,该函数在调用 .parameterize 时将其删除

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

    2) 重新生成所有蛞蝓

    有多种方法,我删除了 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
    

    瞧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-11
      • 2014-04-25
      • 2015-11-04
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多