【问题标题】:Put model associations calls from view to controller将模型关联调用从视图传递到控制器
【发布时间】:2016-12-26 01:40:35
【问题描述】:

在 Rails 4 或更高版本中,如何将模型关联调用从视图传递到控制器?

例如我有:

型号:

class Parent 
  has_many :children
end

class Child
end

控制器:

class ParentController < ApplicationController
  def index
     @parents = Parent.all
  end
end

class ChildrenController < ApplicationController
  def index
     @children = Parent.find(params[:parent_id]).children  
  end
end

查看:

父母/index.html.erb

<% @parents.each do |parent| %>
   <% render parent.children %>
<% end %>

一些部分孩子/_child.html.erb

<%= child.name %>

路由.rb

resources :parents do
    resources :children
end

如何通过在控制器中使用某种逻辑来替换方法 parent.children 的调用 - 例如,需要 url 参数的 ChildrenController::index 方法?

我相信这将使我能够从模型中抽象出视图。

我的意思是抽象 - 如果我更改模型 - 例如,它不会在父子之间有 has_many 关联 - 但仍然想保留视图,那么我将只更改控制器中的代码而不是视图.

此外,我可以将控制器中的模型逻辑提取到某些业务类中,该类将像模型接口一样使用。

我正在尝试构建具有分离的表示层(视图、控制器)和业务层(业务类、活动记录)的两层架构。

或许这种架构可以避免类似 futurelearn 门户网站决定将其 STI 模型(单表)拆分为多个不同模型的情况。但是没有真正的分离它变成了欺骗 Rails 的创造性任务(参见https://about.futurelearn.com/blog/refactoring-rails-sti)。代码有很多关联调用,有必要开发一些方法来保留这些调用(只是因为否则需要更改太多代码)并同时更改模型。

【问题讨论】:

    标签: ruby-on-rails ruby model-view-controller


    【解决方案1】:

    不知道你的意思

    我相信这将使我能够从模型中抽象出视图。

    您没有在视图本身中使用模型。您正在视图中使用 ActiveRecord 关联,我认为这是执行此类操作的正确方法。不确定就读取内存中的所有记录而言,为每个父级渲染所有子级是否正确,但这是一个完全不同的主题。

    FWIW,parent.childrenParent.find(params[:parent_id]).children 都将在后端生成完全相同的 SQL。

    【讨论】:

    • 你好,柴坦亚。请查看问题的编辑版本 - 我在最后添加了一些我的意思的解释。
    • 也许我应该在一个单独的问题中询问 Rails 中是否可以使用两层架构。
    • 如果您最终删除了has_many 关系,您可以在您的 Parent 模型中添加一个方法 children ,该方法将返回关联的孩子。我更喜欢 ActiveRecord 模型来执行 CRUD 操作,因此如果您想在视图中保留 parent.children 调用,我可能会将 children 方法移到关注点。或者,如果您可以在控制器中执行parent.children = children_of(parent_id) 之类的操作,您可以将其移至服务对象。
    【解决方案2】:

    没关系,如果您认为有这样的电话,我相信没有好的方法可以删除它。你唯一能做的——你可以尝试隐藏这个调用,但这不会给你带来真正的抽象。

    但是有一些事情是你需要做的: 1. 添加includes 以在单个查询中加载您的关联

    def index
      @parents = Parent.includes(:children).all
    end
    

    2。如果您的视图中不需要您的父母(不清楚 - 您是否只渲染子部分,或者该视图中有其他线条?),只有孩子 - 您可以加载您的孩子:)

    @children = Children.all
    # or, if your children can be without parents
    @children = Children.where.not(parent_id: nil).all
    

    【讨论】:

      【解决方案3】:

      我想你错过了 belongs_to:

      class Parent 
        has_many :children
      end
      
      class Child
        belongs_to :parent
      end
      

      【讨论】:

      • 我问了一些不同的问题。你能说出有什么不清楚的地方吗?但是,我认为 belongs_to 应该只创建一个使用 child.parent 的选项,我在示例中无论如何都没有使用
      • 有用的信息,但不回答问题
      猜你喜欢
      • 2013-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-08
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      相关资源
      最近更新 更多