标签: nested-resources

REST复杂/复合/嵌套资源

我试图围绕解决基于REST的API中的概念的最佳方式.不包含其他资源的平面资源没有问题.我遇到麻烦的地方是复杂的资源.

例如,我有一本漫画书的资源.ComicBook上有如各种属性author,issue number,date,等.

漫画书也有一份1..n封面清单.这些封面是复杂的对象.它们包含大量关于封面的信息:艺术家,日期,甚至是封面的64位编码图像.

对于GETComicBook我可以回相声,和所有的封面,包括他们的base64'ed图像.获得一部漫画可能不是什么大不了的事.但是假设我正在构建一个客户端应用程序,希望在表格中列出系统中的所有漫画.
该表将包含ComicBook资源中的一些属性,但我们当然不希望显示表中的所有封面.返回1000本漫画书,每本漫画书都有多个封面,这将导致大量数据流过网络,在这种情况下,最终用户不需要这些数据.

我的直觉是制作Cover资源并ComicBook包含封面.所以现在Cover是一个URI.GET漫画书现在可以使用,而不是Cover我们为每个封面发回一个URI 的巨大资源,客户可以根据需要检索封面资源.

现在我在创建新漫画方面遇到了问题.当我创建一个时,我肯定想要创建至少一个封面Comic,事实上这可能是一个商业规则.
所以现在我卡住了,我要么强制客户端通过先提交给执行业务规则Cover,获得URI为盖,然后POST荷兰国际集团一个ComicBook与URI列表,或者我POSTComicBook需要在寻找不同的资源比它吐出出.传入的资源是POSTGET深拷贝,其中传出的GETs包含对依赖资源的引用.

Cover在任何情况下,资源可能都是必要的,因为我确信作为客户,我想在某些情况下解决覆盖方向问题.因此,无论依赖资源的大小如何,问题都以一般形式存在.一般来说,如何处理复杂的资源而不强迫客户只是"知道"这些资源是如何组成的?

api rest resources nested-resources

171
推荐指数
2
解决办法
5万
查看次数

具有嵌套资源的form_for

我有一个关于form_for和嵌套资源的两部分问题.假设我正在编写一个博客引擎,我想将评论与文章联系起来.我已经定义了一个嵌套资源,如下所示:

map.resources :articles do |articles|
    articles.resources :comments
end
Run Code Online (Sandbox Code Playgroud)

评论表单位于文章的show.html.erb视图中,位于文章本身下方,例如:

<%= render :partial => "articles/article" %>
<% form_for([ :article, @comment]) do |f| %>
    <%= f.text_area :text %>
    <%= submit_tag "Submit" %>
<%  end %>
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误,"为nil调用id,这会错误等等".我也试过了

<% form_for @article, @comment do |f| %>
Run Code Online (Sandbox Code Playgroud)

哪个呈现正确但将f.text_area与文章的"文本"字段而不是注释相关联,并在该文本区域中显示了article.text属性的html.所以我似乎也有这个错误.我想要的是一个表单,其'submit'将在CommentsController上调用create action,在params中有一个article_id,例如对/ articles/1/comments的post请求.

我的问题的第二部分是,开始创建评论实例的最佳方法是什么?我正在ArticlesController的show动作中创建一个@comment,因此一个注释对象将在form_for帮助器的范围内.然后在CommentsController的create动作中,我使用从form_for传入的参数创建新的@comment.

谢谢!

ruby-on-rails form-for nested-resources

118
推荐指数
3
解决办法
10万
查看次数

更改URL而不更改资源名称

我正在为一个兔子农民建立一个网站(让我们假装).这个男人密切关注他的兔子,并希望他们都归类.所以我为他建了一个RabbitCategoriesController,并将这一行添加到我的routes.rb中

resources :rabbit_categories
Run Code Online (Sandbox Code Playgroud)

的URL被作为表示向上rabbit_categories,rabbit_categoriew/new

如果我希望网址看起来像rabits/categories rabits/categories/new怎么办?这不是嵌套资源,我只是想改变URL的外观.

当然,如果资源被称为"类别",我可以做到

namespace :rabbits do
  resources :categories
end
Run Code Online (Sandbox Code Playgroud)

有什么办法我可以写,但告诉它使用RabbitCategoriesController而不是Rabbits :: CategoriesController?

routing nested-resources ruby-on-rails-3

38
推荐指数
1
解决办法
2万
查看次数

Rails - link_to,路由和嵌套资源

正如我对嵌套资源的理解,边缘Rails,不应该

link_to 'User posts', @user.posts
Run Code Online (Sandbox Code Playgroud)

指向

/users/:id/posts
Run Code Online (Sandbox Code Playgroud)

routes.rb文件包含

map.resources :users, :has_many => :posts
Run Code Online (Sandbox Code Playgroud)

如果这不是默认行为,可以通过其他方式完成吗?

routes ruby-on-rails nested-resources

27
推荐指数
2
解决办法
3万
查看次数

Rails嵌套奇异资源路由

我有一个简单的用户模型,带有一个单一的嵌套Profile资源,因此在我的routes.rb中我有:

resources :users do
  resource :profile, :only => [:edit, :update, :show]
end
Run Code Online (Sandbox Code Playgroud)

这会生成预期的路线:

edit_user_profile GET    /users/:user_id/profile/edit(.:format)  {:action=>"edit", :controller=>"profiles"}
     user_profile GET    /users/:user_id/profile(.:format)       {:action=>"show", :controller=>"profiles"}
     user_profile PUT    /users/:user_id/profile(.:format)       {:action=>"update", :controller=>"profiles"}
Run Code Online (Sandbox Code Playgroud)

我创建了一个简单的控制器更新方法来更新模型,然后在成功更新时重定向:

def update
  @profile = Profile.find_by_user_id(params[:user_id])
  @user = User.find_by_id(params[:user_id])

  respond_to do |format|
    if @profile.update_attributes(params[:profile])
      format.html { redirect_to( user_profile_path(@user, @profile), :notice => 'Profile was successfully updated.') }
    else
      # ...
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

问题是,一旦提交表单,表单就会重定向到mydomain.com/users/4/profile.22,其中22恰好是配置文件的ID.显然,这会使控制器混淆,因为路由将'22'解释为格式.

我的问题是,如何将其重定向到mydomain.com/users/4/profile呢? 我已经在redirect_to语句中尝试了以下变体而没有效果,它们都会导致相同的错误网址:

redirect_to( user_profile_path(@user), ... )
redirect_to( user_profile_path(@user, @profile), ... )
redirect_to([@user, @profile], ... )
redirect_to( @profile, ... …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails url-routing nested-resources ruby-on-rails-3

17
推荐指数
1
解决办法
3761
查看次数

Rails命名空间与嵌套资源

假设我的应用程序有两个型号,Foo和Bar.

Foo可选择belongs_to Bar.

现在我可以查看单个Foo,或者搜索特定的Foo,而FoosController可以处理所有这些.我的URL就像: foos/1foos/new

有时我想看一个酒吧.BarsController处理它,我得到它: bars/1bars/1/edit.

如果我正在看一个酒吧,我可能想浏览那个酒吧的所有Foos.所以,我想bars/1/foos/看看那些Foos.

嵌套资源非常简单,它看起来像这样:

resources :foo
resources :bar do
  resources :foo
end
Run Code Online (Sandbox Code Playgroud)

然而,作为酒吧的一部分的Foos有点特别,与常规的Foos不同.所以,例如,如果我加载foos/1或者bars/1/foos/1,我会看同样的Foo,但我在每种情况下都专注于不同的信息.

因此,我一直在考虑使用BarFoos控制器来处理Foos,因为它们处于Bar的环境中.但是,如果我将BarFoos嵌入Bar下,那么我的助手将会像bar_bar_foos_pathnew_bar_bar_foo_path.这似乎是多余的.

所以,现在我正在考虑命名空间,这是我以前从未研究过的东西.我在rails指南中看到我可以定义:

namespace "bar" do
  resources :foos
end
Run Code Online (Sandbox Code Playgroud)

如果我这样做,我可以在第二FoosControllerapp/bar/,并且FoosController可以处理一个酒吧里面的Foos与好的帮助,bar_foo_path(:id)而不是bar_bar_foo_path(:id).

但如果我这样做,我BarsController会怎么样?请求如何被路由到BarsController而不是resources :bars我有namespace "bar"

最后,在我的辅助FoosController中我需要做些什么特别的工作来确保与顶级FoosController没有名称冲突?我意识到路由说"命名空间",但其余的ruby代码如何知道app/bar/foos_controller并且app/foos_controller不是同一个类?

谢谢!

routes namespaces ruby-on-rails nested-resources ruby-on-rails-3

16
推荐指数
2
解决办法
1万
查看次数

Rails:获取嵌套资源的父对象

我有一个属于许多不同模型的嵌套资源.例如:

resources :users do
  resources :histories, only: [:show]
end

resources :publications do
  resources :histories, only: [:show]
end

resources :events do
  resources :histories, only: [:show]
end
Run Code Online (Sandbox Code Playgroud)

HistoriesController,我想找到父对象,虽然我很难想到一个干燥的方法来处理这个问题.目前,我能想到的最好的是:

if params[:user_id].present?
  @parent = User.find(params[:user_id])
elsif params[:publication_id].present?
  @parent = Publication.find(params[:publication_id])
elsif . . . .
Run Code Online (Sandbox Code Playgroud)

我有几十个模型,我必须以这种方式分支,这似乎很草率.我不考虑更好的(可能是烘焙的)方法吗?

ruby-on-rails nested-resources

15
推荐指数
2
解决办法
3760
查看次数

Django REST Framework中的嵌套资源

我希望用嵌套资源实现我的新API.

Example: /api/users/:user_id/posts/
Run Code Online (Sandbox Code Playgroud)

将评估特定用户的所有帖子.我还没有看到这个用例的工作示例,也许这不是实现rest API的正确方法?

python django rest nested-resources django-rest-framework

15
推荐指数
2
解决办法
8273
查看次数

RESTful API路由设计:嵌套与非嵌套

我的问题是在为API目的构建URL时嵌套资源的优势.考虑以下两种用于访问员工资源的备选方案:

/api/employees?department=1   # flat

Vs.

/api/departments/1/employees  # nested
Run Code Online (Sandbox Code Playgroud)

现在考虑开发通用库以从API访问REST资源的任务.如果所有路由都是平坦的,那么这样的REST包装器库只需要知道被访问资源的名称:

store.query('employees', {department_id:1})   =>   /api/employees?department=1
Run Code Online (Sandbox Code Playgroud)

但是,如果我们要支持嵌套路由,那么这个包装器需要知道有关嵌套模型和其他资源的额外信息,以便了解如何构建用于引用此类模型的URL.鉴于并非所有模型都嵌套在相同的父资源下,甚至一些模型根本不会嵌套,REST包装器库需要具有某种配置来描述所有这些额外的知识,否则这些知识是不需要的.

所以我的问题是:

  • API中的嵌套资源路由是否有任何实际优势?(这并不意味着最终用户使用,因此拥有更漂亮的URL可以获得更少的收益).

  • 嵌套方法是否真的比平面更好,超越美学,以便证明为支持资源URL构建缺乏统一性而引入的额外努力和复杂性?

另见:https://stackoverflow.com/a/36410780/621809

更新:重要的澄清

我从一些评论和答案中了解到,我对一个方面不够清楚:我并不反对使用/employees/5或等URL来处理单个资源/departments/1.我不认为这是嵌套的.

当我说嵌套资源时,我指的是像/departments/1/employees资源一直在另一个资源的上下文中寻址的URL .主要问题是,对于URL构建,通用库需要知道额外的东西,如"员工嵌套在部门下",但"分支不嵌套在任何东西下".如果所有资源都可以通过REST来解决,但是以平面方式解决,知道如何解决它们会更简单,更容易预测.

当您考虑它时,在数据库中,您不需要知道额外的信息,以便知道如何处理对象集合(例如RDMS中的表).您总是将员工集合称为employees,而不是departments/5/employees.

rest api-design nested-resources restful-url nested-routes

15
推荐指数
2
解决办法
5435
查看次数

在Rails中使用没有父ID的嵌套资源

我有一类称为Imprintables嵌套资源Styles,Brands,Colors,和Sizes.我目前在我的路线文件中有这个:

resources :imprintables do
  resources :styles, :brands, :colors
  resources :sizes do
    collection do
      post 'update_size_order'
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

哪个产生这样的路线:

/imprintables/:imprintable_id/brands
/imprintables/:imprintable_id/colors
/imprintables/:imprintable_id/styles
/imprintables/:impritnable_id/sizes
Run Code Online (Sandbox Code Playgroud)

我不希望所有嵌套资源都绑定到1个特定的imprintable.我希望我的路线看起来像:

/imprintables/brands
/imprintables/styles
/imprintables/colors
/imprintables/sizes
Run Code Online (Sandbox Code Playgroud)

...等等.

什么是最好的方式来解决这个问题?

ruby ruby-on-rails nested-resources nested-routes

13
推荐指数
1
解决办法
2681
查看次数