如何在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
的调用 - 例如,需要url参数的ChildrenController :: index方法?
我相信这将允许我从模型中抽象出来。
通过抽象我的意思是 - 如果我改变模型 - 例如,它不会在父和子之间有has_many关联 - 但仍然想保留视图然后我将只更改控制器中的代码而不是在视图中。
此外,我可以将控制器中的模型逻辑提取到某个业务类,该业务类将充当要使用的模型接口。
我正在尝试构建具有独立的表示层(视图,控制器)和业务层(业务类,活动记录)的双层体系结构。
可能这种架构可以避免像futurelearn门户那样决定将他们的STI模型(单个表)分成几个不同的案例。但是没有真正的分离,它成了欺骗Rails的创造性任务(见https://about.futurelearn.com/blog/refactoring-rails-sti)。代码有很多关联调用,有必要开发smth来保存这些调用(只是因为否则需要更改太多的代码)并同时更改模型。
答案 0 :(得分:0)
不确定你的意思
我相信这将允许我从模型中抽象出来。
您本身并未在视图中使用模型。您在视图中使用ActiveRecord关联,我认为这是执行此类操作的正确方法。不确定为每个父项呈现所有子项是否正确,只要阅读内存中的所有这些记录,但这是一个完全不同的主题。
FWIW,parent.children
和Parent.find(params[:parent_id]).children
都会在后端生成完全相同的SQL。
答案 1 :(得分: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
答案 2 :(得分:-1)
我认为你错过了belongs_to
:
class Parent
has_many :children
end
class Child
belongs_to :parent
end