对于此应用程序,App
有许多Elements
,每个Features
都有许多Elements
。每次AppsController#show
运行时,我都想更新Features
个属性。但是,我遇到了一个问题,因为我必须挖掘每个Element的@app.elements.features
。我似乎无法从我的应用控制器(或features
)拨打App's Show View
。
我在Elements
上嵌入了列出应用Features
和ElementsController#show
的表格,所以我不能称之为ElementsController
或类似的东西。 ,因为那时它永远不会得到更新。我必须找到某种方法在AppsController
中before_action :set_completion, only: :show
def set_completion
@app = App.find(params[:id])
@app.update_attribute(:completion_status,
(((@app.elements.where(completion: true).count) / (@app.elements.count).to_f) * 100 )
)
end
中调用此操作,但这对我来说听起来并非如此。
这是我到目前为止所做的,现在我不知道接下来应该做些什么。什么是完成这项工作的最佳方式?
我的应用控制器(父级):
def update_feature_completion
@app = App.find(params[:app_id])
@element.update_attribute(:element_feature_completion,
(@element.features.where(completion: true).count)
)
end
元素控制器(子):
def set_completion
@parent = Parent.find(params[:id])
@parent.childs.each do |child|
if (child.childs_childs.where(completion: true).count) == (child.childs_childs.count) #if all childs_childs of the child are completed...
then child.update_attribute(:completion, true) #...mark the child as completed.
else child.update_attribute(:completion, false) #if all childs_childs of the child are not completed, then mark the child as not completed
end
#changes child completion status to % of childs_childs completed
child.update_attribute(:child_completion_status,
child.childs_childs.where(completion: true).count / child.childs_childs.count.to_f
)
@parent.update_attribute(:parent_completion_status,
@parent.childs.child_completion_status.sum
)
end
end
修改 到目前为止我所拥有的(不是简单的):
class Parent < ActiveRecord::Base
belongs_to :user
has_many :children, dependent: :destroy
has_many :childs_children, dependent: :destroy
accepts_nested_attributes_for :children
accepts_nested_attributes_for :childs_childs
end
父模型
class Child < ActiveRecord::Base
belongs_to :parent
has_many :childs_children, dependent: :destroy
accepts_nested_attributes_for :childs_children
end
儿童模型
class childs_child < ActiveRecord::Base
belongs_to :child
belongs_to :parent
end
儿童的孩子模型
{{1}}
答案 0 :(得分:1)
这可能最终会让你在后面的路上咬你。每次GET请求到达显示页面时数据库中数据更改的想法都可能导致服务器不必要的压力。想想那些击中您网页的所有网页抓取工具。他们会无意中触发这些数据库事务。
如果要对任何持久数据进行更改,则应通过POST方法完成。操作回调通常不适用于此类工作,通常只应用于身份验证和缓存等操作。那么我可以提供替代解决方案吗?
所以我们从深层嵌套的关系开始,这很好。但是,当我们对应用程序#how的GET请求发生时,我们不必经常进行这些计算,而是首先要查看导致这些更改的原因。您的数据似乎只会在功能更新完成后才会真正更改。这是您应该强制进行这些更改的地方。那么如果你做了类似的事情呢
让我们尝试采用RESTful方法来解决这个问题。由于功能标记为完整,因此还应更新其各自的元素和应用程序。我们还假设在没有将每个要素标记为完整的情况下,元素不能被标记为完整。
在您的应用程序#show页面上我假设您正在显示所有应用程序的元素和元素从属功能。我想你会希望你的用户点击一个功能上的按钮,该功能将该功能标记为完整。因此,让我们制作一条允许我们这样做的RESTful路线。
配置/ routes.rb中
resources :features do
member do
post 'complete' # features#complete
end
end
所以现在我们有一个RESTful路由,它将在FeaturesController中寻找完整的动作。
features_controller.rb
def complete
if @feature.mark_as_complete
# show some message that says "You successfully completed 'Feature A', Good job!"
else
# Respond with nasty error message of why this request couldn't process
end
end
所以现在你有一个适用于该功能的动作。现在,您需要做的就是在遍历每个元素的功能时在您的应用#show页面中创建一个链接
应用程序/视图/应用/ show.html.haml
- @app.elements.each do |element|
- element.features.each do |feature|
= feature.name
= link_to complete_feature_path(feature), method: :post
当用户完成每项功能时,他们可以点击将发布帖子方法的链接发送到功能#完成操作
class Feature < ActiveRecord::Base
def mark_as_complete
self.update_attributes(completion: true)
self.element.update_completion_status
end
end
class Element < ActiveRecord::Base
def update_completion_status
if (self.feautres.where(completion: true).count) == (self.features.count) # if all features are complete
self.update_attributes(completion: true)
self.update_attributes(feature_completion_status: calculate_percent_complete)
self.app.update_completion_status
else
self.update_attributes(feature_completion_status: calculate_percent_complete)
end
end
private
def calculate_percent_complete
self.features.where(completion: true).count / child.childs_childs.count.to_f
end
end
class Feature < ActiveRecord::Base
def mark_as_complete
self.update_attributes(completion: true)
self.element.update_completion_status
end
end
class App < ActiveRecord::Base
def update_completion_status
# similar to that of Element I assume
end
end
这样,只有在发出POST请求以将功能标记为已完成时,才会更新相应的数据。您应该在应用程序中执行的所有操作#show action是提供要显示的相应对象。
答案 1 :(得分:0)
最后一段代码如下:
@parent.update_attribute(:parent_completion_status,
(@parent.children.sum(:child_completion_status) / @parent.children.count) * 100
)
这基本上通过找出所有:parent_completion_status
完成的百分比来找到children
完成的百分比。
我知道这令人困惑,但我相信那里的某个人能够理解它。当我提出这个问题时,我无法以原来想要的方式解决这个问题。
建议如果您尝试执行类似的操作,请尝试按照我所做的步骤进行操作,除非有一种更简单的方法适用于您。