我有一个模拟房子的应用程序。 House has_many Rooms,Rooms has_many Lights和Small_appliances等。我还有一个名为Calculator的控制器,它是应用程序的访问方式。使用计算器控制器将数据添加到房屋(及其房间)。然后生成一个报告,该报告位于app / views / calculator / report.html.erb。
我的问题是报告的所有计算和逻辑应该在哪里?目前我在视图中都有这一切,在calculator_helper中有一些东西。通常这会出现在模型中,对吧?但是Calculator没有生成的模型。这是什么标准?
这是计算器控制器。
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
答案 0 :(得分:5)
有几种方法可以接近它,但逻辑肯定不属于视图。如果我正确地阅读您的描述,您可以在清晰的层次结构中将各种模型相互关联,层次结构的顶部是House模型。在这种情况下,我会向House模型添加一组适当的方法方法,这些方法可能包括调用与给定House实例关联的Room模型中的计算方法以及关联线。通过这种方式,可以在每个级别执行相关计算,并通过在House模型级别组合一个或多个方法,您可以使用干净,富有表现力和可维护的方式来处理计算。
要做的一件事是确保DB可以执行的任何计算。例如,如果计算房间模型可以通过简单地查询它自己的数据来进行,那么通过所有方法,使用ActiveRecord调用这种较低级别计算逻辑的能力将该计算负担推送到DB。查看API docs了解详情。
我会非常仔细地查看您想要的逻辑,看看它是如何被推入模型的,因为它可能属于它所属的位置,接近计算的实际数据,并且在特定于数据的类结构中;我不会创建一个模型来处理计算逻辑,除非你真的需要由于某种原因持久存储计算。
答案 1 :(得分:1)
我会在RAILS_ROOT / lib /中创建一个类,例如,计算器并将代码放在那里。
/ lib /中的类应该在应用程序的任何位置加载。
您还可以在/ app / models /中创建纯红宝石对象。没有理由他们都必须继承ActiveRecord :: Base
答案 2 :(得分:1)
好的,现在我可以看到发布的代码了。我可以看到calculator_controller实际上没有计算,它们是否在视图中?试试这种方法:
我之前的回复:
如果业务逻辑非常简单并且仅在此Web应用程序后面使用,那么您可以将其放在app / models文件夹中。
class MyCoolClass
def initialize(clues)
@other_things = OtherThing.all
end
def do_cool_thing; end
def calculate_coolness
@other_things.length
end
end
然后在您的控制器中,创建模型的实例
def index
@mcc = MyCoolClass "A clue as to what I want"
render
end
然后在您的模板中,您可以访问它
<%=h @mcc.calculate_coolness %>
请注意,@ other_things是MyCoolClass的 instance__variable ,如果没有定义访问器方法,模板通常无法访问
答案 3 :(得分:0)
这完全取决于您正在创建的数据类型。计算器控制器是什么样的?
您可以在/ lib中创建自己的类并在模型中使用它们,这可以是将逻辑与控制器/帮助器分开的好方法。你有什么理由不能在模型中加入一些逻辑吗?