Rails 应用程序中的计算逻辑应该放在哪里?
我有一个为房子建模的应用程序。 House has_many Rooms、Rooms has_many Lights 和 Small_appliances 等。我还有一个名为 Calculator 的控制器,这就是访问应用程序的方式。使用计算器控制器将数据添加到房屋(及其房间)。然后生成一个报告,该报告位于app/views/calculator/report.html.erb。
我的问题是报告的所有计算和逻辑应该放在哪里?目前我已经在视图中看到了所有内容,其中一些内容在calculator_helper 中。通常这会出现在模型中,对吗?但计算器没有生成模型。这样做的标准是什么?
这是计算器控制器。
class CalculatorController < ApplicationController
def index
end
def save_house
@house = House.new(params[:house])
respond_to do |format|
if @house.save
format.html { render :action => 'add_rooms', :id => @house }
format.xml { render :xml => @house, :status => :created, :location => @house }
else
format.html { render :action => 'index' }
format.xml { render :xml => @house.errors, :status => :unprocessable_entity }
end
end
end
def add_rooms
@house = House.find(params[:id])
@rooms = Room.find_by_house_id(@house.id)
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding rooms"
redirect_to :action => 'index'
end
def add_room
@room = Room.new(params[:room])
@house = @room.house
respond_to do |format|
if @room.save
flash[:notice] = "Room \"#{@room.name}\" was successfully added."
format.html { render :action => 'add_rooms' }
format.xml { render :xml => @room, :status => :created, :location => @room }
else
format.html { render :action => 'add_rooms' }
format.xml { render :xml => @room.errors, :status => :unprocessable_entity }
end
end
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding a room"
redirect_to :action => 'index'
end
def report
flash[:notice] = nil
@house = House.find(params[:id])
@rooms = Room.find_by_house_id(@house.id)
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before generating a report"
redirect_to :action => 'index'
end
end
I have an app that models a House. The House has_many Rooms, Rooms has_many Lights and Small_appliances, etc. I also have a controller called Calculator that is how the app is accessed. Data is added to the house (and its rooms) using the Calculator controller. Then a report is generated, which is located at app/views/calculator/report.html.erb.
My question is where should all the calculations and logic for the report go? Currently I have it all in the view, with some things in calculator_helper. Normally this would go in the model, right? But Calculator doesn't have a model that was generated. What is the standard for this?
Here is the calculator controller.
class CalculatorController < ApplicationController
def index
end
def save_house
@house = House.new(params[:house])
respond_to do |format|
if @house.save
format.html { render :action => 'add_rooms', :id => @house }
format.xml { render :xml => @house, :status => :created, :location => @house }
else
format.html { render :action => 'index' }
format.xml { render :xml => @house.errors, :status => :unprocessable_entity }
end
end
end
def add_rooms
@house = House.find(params[:id])
@rooms = Room.find_by_house_id(@house.id)
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding rooms"
redirect_to :action => 'index'
end
def add_room
@room = Room.new(params[:room])
@house = @room.house
respond_to do |format|
if @room.save
flash[:notice] = "Room \"#{@room.name}\" was successfully added."
format.html { render :action => 'add_rooms' }
format.xml { render :xml => @room, :status => :created, :location => @room }
else
format.html { render :action => 'add_rooms' }
format.xml { render :xml => @room.errors, :status => :unprocessable_entity }
end
end
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding a room"
redirect_to :action => 'index'
end
def report
flash[:notice] = nil
@house = House.find(params[:id])
@rooms = Room.find_by_house_id(@house.id)
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before generating a report"
redirect_to :action => 'index'
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有几种方法可以处理它,但逻辑肯定不属于视图。如果我正确地阅读了您的描述,您可以在清晰的层次结构中相互关联各种模型,层次结构的顶部是 House 模型。在这种情况下,我将向 House 模型添加一组适当的方法,该方法可能由对与给定 House 实例关联的 Room 模型中的计算方法的调用以及关联线下的调用组成。这样,可以在每个级别执行相关计算,并且通过在 House 模型级别编写一个或多个方法,您可以采用一种干净、富有表现力且可维护的方式来处理计算。
要做的一件事是确保数据库可以执行任何计算。例如,如果 Room 模型可以通过简单地查询它自己的数据来完成计算,那么无论如何都要使用 ActiveRecord 调用此类较低级别计算逻辑的能力将该计算负担推给数据库。有关详细信息,请查看 API 文档。
我会非常仔细地查看您想要的逻辑,并了解如何将其推入模型中,因为这可能是它所属的位置,靠近计算的实际数据,并且位于专门表示该数据的类结构中;我不会创建一个模型只是为了处理计算逻辑,除非您确实需要出于某种原因持久存储计算。
There are a few ways to approach it, but the logic certainly does not belong in the view. You have the various models associated with one another in a clear hierarchy with the top of the hierarchy being the House model, if I am reading your description correctly. That being the case, I would add an appropriate method of set of methods to the House model that may be composed of calls to calculation methods in the Room models associated with a given House instance and on down the line of association. That ways the relevant calculation can be performed at each level and through composing one or more methods at the House model level you are able to have a clean, expressive and maintainable way to deal with calculations.
One thing to do, as well, would be to make sure that any calculations that can be performed by the DB are. For example, if there is a calculation that a Room model can do by simply querying it's own data then by all means push that computational burden to the DB using the ability of ActiveRecord to invoke such lower level calculation logic. Check out the API docs for the details.
I would look very carefully at the logic you want and see how it can be pushed into the model since that is probably where it belongs, close to the actual data of the calculations, and within the class structures that represent that data specifically; I would not create a model just to handle the calculation logic unless you really need to store the calculations persistently for some reason.
我会在 RAILS_ROOT/lib/ 中创建一个名为 Calculator 的类,并将代码放入其中。
/lib/ 中的类应该加载到应用程序中的任何位置。
您还可以在 /app/models/ 中创建一个普通的 ruby 对象。没有理由它们都必须继承 ActiveRecord::Base
I would create a class in RAILS_ROOT/lib/ called, for example, Calculator and put the code in there.
Classes in /lib/ should be loaded an available anywhere in your app.
You can also create a plain ruby object in /app/models/. There's no reason they all have to inherit from ActiveRecord::Base
好的,现在我可以看到发布的代码了。我可以看到计算器控制器实际上没有计算,它们在视图中吗?尝试这种方法:
我之前的回答:
如果业务逻辑相当简单并且仅在该 Web 应用程序后面使用,那么您可以将其放在 app/models 文件夹中。
然后在控制器中创建模型的实例
然后在模板中可以访问它
请注意,@other_things是MyCoolClass的instance__variable,并且通常无法在未定义访问器方法的情况下访问模板
Ok, now I can see the code posted. I can see the calculator_controller actually has no calculations in it, are they in the views?. Try this approach:
My prior respose:
If the business logic is fairly simple and only used behind this web app, then you can put it in your app/models folder.
Then in your controller, create an instance of your model
Then in your templates you can access it
Note that @other_things is an instance__variable of MyCoolClass and generally not accessible to the templates without accessor methods being defined
这一切都取决于您创建的数据类型。计算器控制器是什么样子的?
您可以在 /lib 中创建自己的类并在模型中使用它们,这是将逻辑与控制器/帮助器分离的好方法。您无法将某些逻辑放入模型中是否有原因?
This all depends on what kind of data you're creating. What does the calculator controller look like?
You can create your own classes in /lib and use them in your models, which can be a good way to separate out logic from the controller/helpers. Is there a reason why you couldn't put some of the logic in the models?