DRY - in controller or model????

Hello.

I'm trying to make clean efficient code and would like to find out if there is a "BEST" way to write code. I want this to run quickly and efficiently for my app.

I've got a form that needs a select list created for new and edit functions. Same list.

Do I do this in the controller and reference @list in the forms?

def new   @list = %w { apple orange banana } end

def edit   @list = %w { apple orange banana } end

Or do I put this in the model and just reference model.list in the forms?

def list   %w { apple orange banana } end

Or is there a better way?

Thanks!

I'd do a before filter (in controller)

before_filter :populate_list, :only => [:new, :edit]

def populate_list   @list = %w(...) end

Jason

Becca Girl wrote:

Or is there a better way?

Thanks!

Models should contain functionality to expose and manipulate their state and nothing more. If an actual model contains the attributes that you listed above then it's find to ask the model for a list from the controller.

Controllers are solely responsible for mapping views to models. Their functionality should be focussed around this task. If a controller doesn't need to have access to a model's state (which is the preferred way) then it shouldn't.

Lastly, a model should never have ANY knowledge of it's business context within the application. It should be completely application agnostic.

hth

ilan

Ilan Berci wrote: If an actual model contains the attributes that you

listed above then it's find to ask the model for a list from the controller.

Thanks for the replies.

Just for clarification, if, for example, my order form is in the grocery model and the items in the list are part of a produce model, then it's not good practice to ask the grocery model to find the list of produce, correct?

Becca Girl wrote:

Ilan Berci wrote: If an actual model contains the attributes that you

listed above then it's find to ask the model for a list from the controller.

Thanks for the replies.

Just for clarification, if, for example, my order form is in the grocery model and the items in the list are part of a produce model, then it's not good practice to ask the grocery model to find the list of produce, correct?

If there is an association (one to many, many to many) between grocery and produce then it's perfectly ok to ask the grocery model for it's list of produce. In fact this is exactly how "has_many()" works!

class Produce   belongs_to :grocery end

class Grocery   has_many :produces end

Grocery.new.produces

hth

ilan

Ilan Berci wrote:

class Produce   belongs_to :grocery end

class Grocery   has_many :produces end

Grocery.new.produces

I understand the concept and "think" that I almost have it. I do have my model relationship as you noted.

I have a belongs_to relationship and I have a def for the produce_list which then I think duplicates rails functionality.

So if I'm populating a select list, what would the select statement look like, i.e, how do I reference the produce list?

Currently I have something like this: <%= f.select :produce_id, Order.produce_list %>

Becca Girl wrote:

I understand the concept and "think" that I almost have it. I do have my model relationship as you noted.

I have a belongs_to relationship and I have a def for the produce_list which then I think duplicates rails functionality.

So if I'm populating a select list, what would the select statement look like, i.e, how do I reference the produce list?

Currently I have something like this: <%= f.select :produce_id, Order.produce_list %>

something like.. <%= f.select :procude_id, options_from_collection_for_select(@grocery.produces, "id", "name") %>

hth..

ilan

Here's what I had when I started asking the question and now after reading the posts, I'm wondering if it's correct or what needs to change. The controller does not have any related code. Here's the model and view.

model: class Order < ActiveRecord::Base   belongs_to :customer

  def self.customer_list     Customer.find(:all).collect{|c| [c.name, c.id]}   end end

view: <%= f.select :customer_id, Order.customer_list %>

Thanks.

Of possible interest--this very similar thread:

http://groups.google.com/group/rubyonrails-talk/browse_frm/thread/16eff66dda41b846

If you want to emulate that (and I'm a pretty big noob, so you may not) you'd put that function in the Customer model I think...

HTH,

-Roy

Actually this advice goes against the prevailing wisdom that controllers should be skinny and models should be fat.

http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model http://therailsway.com/2007/6/1/railsconf-recap-skinny-controllers http://www.robbyonrails.com/articles/2007/06/19/put-your-controllers-on-a-diet-already

I'm not sure what business logic really means, there's no real definition of it. But in general:

Views should have very little code, and what's there should be dealing with presentation NOT the domain model. Controller logic should be confined to user interface logic. The Models should be where the logic related to "business" rules lives. By model here I mean primarily ActiveRecord models in Rails, although these can be supplemented or even replaced in some applications.

Controller logic should be confined to user interface logic. The Models should be where the logic related to "business" rules lives. By model here I mean primarily ActiveRecord models in Rails, although these can be supplemented or even replaced in some applications.

Another way to say this: Anything a user can do to the data, thru the View, a unit test can do to the data, thru the Model.

Controllers should add no business rules.

(I'll get back to you when all the Rails apps I maintain follow that rule!:wink:

Thanks so much for the great help! There's a bit of conflicting advice, but you guys are great! Thanks for the links too.

Phlip wrote:

Controller logic should be confined to user interface logic. The Models should be where the logic related to "business" rules lives. By model here I mean primarily ActiveRecord models in Rails, although these can be supplemented or even replaced in some applications.

Another way to say this: Anything a user can do to the data, thru the View, a unit test can do to the data, thru the Model.

Controllers should add no business rules.

(I'll get back to you when all the Rails apps I maintain follow that rule!:wink:

Rick and Phlip phrased it much better than I.. sorry if this lead to some confusion..

ilan