【问题标题】:Rails: List all of Parent's children in Parent's ShowRails:在Parent's Show中列出所有Parent的孩子
【发布时间】:2016-07-12 15:55:26
【问题描述】:

在我的 rails 应用程序中,我可以为该客户端创建一个客户端和一个工作器。目前,我可以列出所有已创建的工人。但是,此列表也包括其他客户的工作人员。

如何在客户端显示页面中仅列出特定客户端的所有工作人员?

我感觉这与我的 client#show 方法有关。

  class ClientsController < ApplicationController
  before_action :set_client, only: [:show, :edit, :update, :destroy]

  # GET /clients
  # GET /clients.json
  def index
    @clients = Client.all
  end

  # GET /clients/1
  # GET /clients/1.json
  def show
    @workers = Worker.all
  end


  # views/clients/show.html.erb
  <ul>
   <% @workers.each do |worker| %>
    <li><%= worker.first_name %> <%= worker.client.business_name %></li>
   <% end %>
  </ul>

提前致谢。

【问题讨论】:

    标签: ruby-on-rails ruby model-associations


    【解决方案1】:

    在您的ClientsController 中,您的show 操作应该显示Client,但您的代码是从Worker 获取的。你想要更多这样的东西:

    def show
      @client = Client.includes(:workers).find(params[:id])
    end
    
    # app/views/clients/show.html.erb
    <% @client.workers.each do |worker| %>
      <%= worker.name %>
    <% end %>
    

    注意:您似乎还有一个 set_client 方法,它正在检索当前的 Client 并设置 @client 实例变量。这是一种反模式。在许多情况下,您会检索不需要的数据,并使您的操作难以一目了然。少量的非逻辑重复总比混淆抽象要好!

    【讨论】:

    • 我想我明白了。使用上面的代码,我首先在实例变量@client 中包含与客户端关联的所有工作人员。然后我打电话给客户的工人,因此所有与该工人相关的属性(即名称)。
    • 科里沃德,我不太明白你的笔记。可以保持原样还是我应该改变它?
    • 使用.includes 急切加载:workers 做得很好。这样做会根据您的使用方式减少数据库查询的数量,从而提高性能。
    • @hp001 它会很好地发挥你的作用。这更多的是设计问题,并使您的代码更容易更改。如果您有兴趣了解更多信息,我强烈推荐 Sandi Metz 的书,Practical OO Design in Ruby
    【解决方案2】:

    直接回答您的问题:

    def show
      @client  = Client.find params[:id]
      @workers = @client.workers
    end
    

    假设您正在使用资源路由,params 哈希将包括 URL 路径的 id 部分,这里是 /clients/:id。因此,您可以使用它来找到有问题的特定客户,然后为该客户获取作品。

    但是您可能想在此处阅读有关此主题的大量详细信息: http://guides.rubyonrails.org/routing.html#nested-resources

    【讨论】:

    • 我喜欢这段代码。这很容易理解。谢谢。
    【解决方案3】:

    首先,您应该在客户端和工作人员之间定义一个 has_many 关系。

    class User < ApplicationRecord
      has_many :workers
    end
    
    class Worker < ApplicationRecord
      belongs_to :user
    end
    

    更多信息:Active Record has_many association

    然后在“显示”操作中,您应该获得与特定用户相关的工作人员。例如:

    # GET /clients/1
    # GET /clients/1.json
    def show
      user = User.find(params[:id]) # find specific user
      @workers = user.workers # get workers related to this user
    
      # or you can do something like this
      @workers = Worker.where(user_id: params[:id])
    end
    

    【讨论】:

    • 我喜欢第二个选项。看起来我可以在一行代码中完成所有事情。太棒了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多