2016-12-26 108 views
-1

如何在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 %> 

route.rb

resources :parents do 
    resources :children 
end 

如何可以通过在控制器使用以某种方式逻辑替代方法parent.children的呼叫 - 例如,ChildrenController ::需要url参数的索引方法?

我相信这将允许我从模型中抽象视图。

通过抽象我的意思是 - 如果我改变模型 - 例如,它不会有父母和子女之间的has_many关联 - 但仍然想保留视图,那么我将只改变控制器中的代码不在视图。另外,我可以将控制器中的模型逻辑提取到一些业务类,它将像模型接口一样使用。

我正尝试用独立的表示层(视图,控制器)和业务层(业务类,activerecords)构建两层架构。

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

回答

-1

我想你错过把belongs_to

class Parent 
    has_many :children 
end 

class Child 
    belongs_to :parent 
end 
+0

我问不同的东西。你能否告诉我有什么不清楚的问题。不过,我认为belongs_to应该创建一个选项来使用child.parent,但我并没有在例子中使用 – littlewhywhat

+0

有用的信息,但不回答问题 –

0

不知道你的

的意思我相信这会让我从模型抽象的视图。

您在视图本身中没有使用模型。你在视图中使用ActiveRecord关联,我认为这是正确的方式来做这种事情。不知道为每个父母提供所有孩子是否是正确的事情,只要阅读记忆中的所有记录,但这是一个完全不同的话题。

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

+0

你好,Chaitanya。请参阅编辑版本的问题 - 我在最后添加了一些我的意思的解释。 – littlewhywhat

+0

也许我应该问一个单独的问题,如果两个分层架构可能在Rails中。 – littlewhywhat

+0

如果最终删除'has_many'关系,则可以在父模型中添加一个方法'children',它将返回关联的子对象。我更喜欢ActiveRecord模型来做CRUD操作,所以如果你想在视图中保留'parent.children'调用,我可能会将子方法移到一个问题上。或者,如果您在控制器中执行类似'parent.children = children_of(parent_id)'的操作,则可以将其移动到服务对象。 –

0

没关系,如果你在你看来有这样的电话,我相信没有好的办法去除它。你可以做的唯一事情 - 你可以尝试隐藏这个电话,但这不会给你带来真正的抽象。

但也有一些事情,你需要做的: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 
相关问题