【问题标题】:How do I write the routes for these resources?如何为这些资源编写路线?
【发布时间】:2016-04-23 02:23:37
【问题描述】:

对于我的 rails 应用程序,关联如下:

  • 一个用户有很多书签,属于用户。
  • 一个用户有很多朋友。
  • 一个用户有很多提醒。
  • 一个用户有很多 cmets。
  • 一个书签有许多 cmets。
  • 评论属于用户,属于书签。
  • 友谊属于用户。
  • 提醒属于用户

我的 routes.rb 文件:

Rails.application.routes.draw do

  root 'welcome#index'
  get 'home', :to => 'home#index'
  get 'searchApis', :to => 'home#searchApis'

  devise_for :users, :controllers => { registrations: 'registrations' }

  resources :users, shallow: true do
    resources :bookmarks, except: :new
    resources :friendships, only: [:index, :show, :destroy]
    resources :reminders
  end

  resources :bookmarks, shallow: true do
    resources :comments
  end

end

我是否正确地写出这些路线?

当我rake routes 时,我收到了两次bookmarks#index,所以我很困惑。其中一个的前缀是bookmark,另一个是bookmarks。为什么会这样?

据我了解,应用程序不需要查看索引中的所有书签,因为它们只对创建它们的用户可见。但是,我希望提醒对用户的朋友可见。

如果可能的话,我希望得到清理路线的建议。我真的怀疑我这样做是否正确。

【问题讨论】:

  • 另外,我觉得 user_bookmarks_path 和 bookmarks_path 是多余的,我不知道如何解决。
  • 想想您希望书签索引如何显示——您希望它围绕用户的书签还是站点范围的书签?

标签: ruby-on-rails ruby routing nested-routes


【解决方案1】:

Shallow 仅提供 :index、:new 和 :create。所以你得到了两次索引。一次来自用户和其他书签 - cmets。

在帖子开头重新阅读您的关联,并且 cmets 属于_同时属于用户和书签时,创建多态关系可能是一个好主意。

为您的模型提供粗略的指南,

class Comment < ActiveRecord::Base
  belongs_to :messages, polymorphic: true
end

class User < ActiveRecord::Base
  has_many :comments, as: :messages
end

class Bookmark < ActiveRecord::Base
  has_many :comments, as: :messages

然后是rails generate migration Comments,如果你还没有的话,让它看起来像下面这样:

class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :name
      t.references :messages, polymorphic: true, index: true
      t.timestamps null: false
    end
  end
end

否则,运行迁移以将列添加到您的 Comment 模型。即rails g migration AddMessagesToComments messages:references 但是一定要打开你上面命名的新迁移文件,并在rake db:migrate之前添加polymorphic: true

【讨论】:

  • 我投了赞成票,因为我不知道 shallow 只允许 index/new/create 动作
【解决方案2】:

我对您的规范的解释:

#config/routes.rb
resources :users, only: [] do #-> show a user's collections (no edit)
   resources :bookmarks, shallow: true, except: [:new, :edit, :update]                 #-> url.com/bookmarks/:id
   resources :comments, :friendships, :reminders, shallow: true, only: [:index, :show] #-> url.com/comments/:id
end

resource :bookmarks, except: :index do #-> url.com/bookmarks/:id
   resources :comments #-> url.com/bookmarks/:bookmark_id/comments/:id -- should be scoped around current_user
end

对于 cmets 控制器,执行以下操作:

#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
   def new
      @bookmark = Bookmark.find params[:bookmark_id]
      @comment  = @bookmark.comments.new
   end

   def create
      @bookmark     = Bookmark.find params[:bookmark_id]
      @comment      = @bookmark.comments.new bookmark_params
      @comment.user = current_user
      @comment.save
   end
end

不要制作 welcomehome 控制器,你不需要它们。

您可以在 application 控制器中放置副手操作:

#config/routes.rb
root                   'application#index'
get 'home',        to: 'application#home'
get 'search_apis', to: 'application#search_apis'

当然,这有点像antipattern(你最终会膨胀你的ApplicationController),但如果你在其他控制器中只有模糊的“一次性”操作,你将最适合使用以上。


另外,对于 URL,仅使用 snake_caselowercase - HTTP's spec 确定所有 URL 都应以小写形式处理:

将方案和主机转换为小写。方案和主机 URL 的组成部分不区分大小写。大多数规范化器将 将它们转换为小写。示例:→ http://www.example.com/

虽然这仅适用于域/主机,但它也适用于 URL 本身。

【讨论】:

  • 这很有帮助。我对此相当陌生,因此您对我的应用程序控制器逻辑的重构确实为我清理了一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多