如何在视图中link_to主对象看起来更干净?

时间:2016-05-11 03:57:56

标签: ruby-on-rails ruby dry link-to

我有用户模型,有很多细节。

在详细信息列表(索引)页面(./details)中有一个link_to支持主表,或拥有详细信息的用户(./user/1)。

基本上,我想知道是否有办法制作link_to方法的语法,看看任何更清洁的ruby或rails我不知道的约定。

<% @details.each do |detail| %>
  <tr>
    <td><%= detail.name %></td>
    <td><%= link_to User.find_by_id(detail.foreign_key_id).name, \
            User.find_by_id(detail.foreign_key_id) %></td>
    ...

这很好用,但我似乎记得在某些时候看到了更清晰的语法。

[编辑] 同样在这种情况下,我有两种方式可以将用户与细节相关联。

我想到的数据模型类似于 Project ,因此我将以这种方式呈现问题。因此,用户既可以是项目的所有者,也可以是项目的赞助商

因此,User类将具有以下内容....

 class User < ActiveRecord::Base
   has_many :owned_projects, class_name: "Project", foreign_key: :owner_id
   has_many :sponsored_projects, class_name: "Project", foreign_key: :sponsor_id
 end

然后Project类将在其定义

中具有此功能
class Project < ActiveRecord::Base
  belongs_to :owner,    :foreign_key => :owner_id,    :class_name => "User"
  belongs_to :sponsor,  :foreign_key => :sponsor_id,  :class_name => "User"
end

项目表包含 owner_id 字段和 sponsor_id 字段,因此用户类可以链接两次到项目表。

鉴于所有这些,回到手头的问题,我不知道如何使用@Michael Gaskill

所描述的更清晰的语法

如果看起来像这样,会是这样的吗?%= link_to @project.sponsor.name, project.sponsor_id %></td>

Rails magic 似乎没有想到这一点,或者我配置错了。

我已经测试过后续,这将会起作用,正如我之前提到的那样,但我试图确保没有更清洁的方法。

(目标是查看有关详细信息的页面,或此示例中的 Project ,并查看与其关联的 User 的两个类别,并让他们的名称是其 show 页面配置文件的可点击链接)

<p>
  <strong>Name:</strong>
  <%= @project.name %>
</p>

<p>
  <strong>Owner:</strong>
  <%= link_to User.find_by_id(@project.owner_id).name, User.find_by_id(@project.owner_id) %>
</p>

<p>
  <strong>Sponsor:</strong>
  <%= link_to User.find_by_id(@project.sponsor_id).name, User.find_by_id(@project.sponsor_id) %>
</p>

1 个答案:

答案 0 :(得分:2)

如果您的关系设置正确,您应该可以执行以下操作:

%= link_to detail.user.name, detail.user %></td>

如果可以提供帮助,您希望避免在视图中执行任何ActiveRecord查询。如果您必须在视图中执行查询,请确保您不复制它们。视图中的查询往往会导致N + 1问题,并且重复它们会导致它变为2 *(N + 1)或更差。

根据您问题中显示的新关系,您应该可以使用它来代替您的观看代码:

<p>
  <strong>Name:</strong>
  <%= @project.name %>
</p>

<p>
  <strong>Owner:</strong>
  <%= link_to @project.owner.name, @project.owner) %>
</p>

<p>
  <strong>Sponsor:</strong>
  <%= link_to @project.sponsor.name, @project.sponsor) %>
</p>

简单地说,Rails魔术知道如何遍历关系以从每个赞助商和所有者模型对象中检索名称。同样,link_to知道如何从赞助商和所有者(作为link_to的第二个参数给出)自动检索路径信息,以便为每个对象创建正确的链接。请注意,当您使用模型对象(例如&#34;所有者&#34;)而不是object_id(例如&#34; owner_id&#34;)时,这是有效的。

link_to API documentation为如何将link_to与模型数据结合使用提供了更深入的指导。示例#2演示了此答案使用的确切技术;但是,我们选择直接从ActiveRecord模型(作为所有者或赞助商名称)提供链接文本,而不是像在示例中那样对其进行硬编码。

通过使用路由助手来定义要使用的路径,您还可以更明确地指定要链接到的路由。让我们制作一个类似的视图页面,显示如何链接到项目所有者和赞助商的编辑页面:

<p>
  <strong>Name:</strong>
  <%= @project.name %>
</p>

<p>
  <strong>Owner:</strong>
  <%= link_to @project.owner.name, edit_owner_path(@project.owner) %>
</p>

<p>
  <strong>Sponsor:</strong>
  <%= link_to @project.sponsor.name, edit_owner_path(@project.sponsor) %>
</p>

您可以使用Rails创建的任何路线助手来导航到您的任何模型&#39;动作。要找出可用于项目的路径助手,可以从命令行运行rake routes,并查看如下结果:

      Prefix Verb   URI Pattern                  Controller#Action
    projects GET    /projects(.:format)          projects#index
             POST   /projects(.:format)          projects#create
 new_project GET    /projects/new(.:format)      projects#new
edit_project GET    /projects/:id/edit(.:format) projects#edit
     project GET    /projects/:id(.:format)      projects#show
             PATCH  /projects/:id(.:format)      projects#update
             PUT    /projects/:id(.:format)      projects#update
             DELETE /projects/:id(.:format)      projects#destroy
       users GET    /users(.:format)             users#index
             POST   /users(.:format)             users#create
    new_user GET    /users/new(.:format)         users#new
   edit_user GET    /users/:id/edit(.:format)    users#edit
        user GET    /users/:id(.:format)         users#show
             PATCH  /users/:id(.:format)         users#update
             PUT    /users/:id(.:format)         users#update
             DELETE /users/:id(.:format)         users#destroy

这是通过在config/routes.rb

中包含这些定义而定义的标准路线集
resources :project
resources :user

rake routes的输出中,您会看到&#34;前缀&#34;中显示的路线助手。左栏。这些是您用于向link_to提供显式页面链接的标识符。这些被称为&#34;前缀&#34;,因为它们与&#34;路径&#34;一起使用。或者&#34; url&#34;分别生成相对路径或绝对URL。考虑这些用途:

user_path(@project.owner)      # ==> "/user/9"
user_url(@project.sponsor)     # ==> "http://example.com/user/23"
new_user_path                  # ==> "/user/new"
new_user_url                   # ==> "http://example.com/user/new"

请注意,其中一些路线助手必须指定一个参数,而另一些则不需要。您可以从rake routes输出中读取此信息,因为参数是按照替换参数的出现顺序(例如:id)提供的,不包括可选的替换参数(例如(。:format))。资源的标准路由集为您提供了可以使用的路由助手:

users_path                     # ==> "/user"
new_user_path                  # ==> "/user/new"
user_path(@user)               # ==> "/user/139"
edit_user_path(@user)          # ==> "/user/139/edit"

其他默认路线通常不会直接在您的项目中使用,因此您不会直接引用它们。

因此,只要有模型对象,就可以使用隐式路径方法创建要使用的任何链接:

<%= link_to @user.name, @user %>

或路径助手接近:

<%= link_to @user.name, user_path(@user) %>

这两者都应该为#69用户生成相同的链接,&#34; Scott Tenorman&#34;:

<a href="/user/69">Scott Tenorman</a>

这就是神奇的一切。它根本不是真正的魔术,而是一系列精心设计的智能约定,它们协同工作,使易于操作变得容易。一旦你知道它们是如何工作的。快乐联系!