# MVC Design Question - dependent objects

**URL:** <https://www.ruby-forum.com/t/mvc-design-question-dependent-objects/132403>\
**Category:** Rails\
**Created:** [March 19, 2008, 7:25pm UTC](https://www.ruby-forum.com/t/mvc-design-question-dependent-objects/132403 "2008-03-19T19:25:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 19, 2008, 7:25pm UTC](https://www.ruby-forum.com/t/mvc-design-question-dependent-objects/132403/1 "2008-03-19T19:25:43Z")

</div>

Given

entity has\_one, :client

client belongs\_to :entity

When creating a new client and an instance of entity.name does not exist  
then I want to add an entity and a client. (This is done and works)

If entity.name exists then I want to check if entity.client also exists.

If entity.client exists then I want to return both the entity and client  
instances from the database to the user and ask if this is the client  
they wished to create.

If entity.client does not exist then I want to return the entity to the  
user and ask if this is the entity that they wish to add as a client and  
allow them to add the client role to that entity.

So, does the code for this sort of checking and shuffling of data belong  
mainly in the model or mainly in the controller? Are there Rails  
specific considerations that bear upon the answer?

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 20, 2008, 12:14am UTC](https://www.ruby-forum.com/t/mvc-design-question-dependent-objects/132403/2 "2008-03-20T00:14:16Z")

</div>

The trend seems to be to keep as much logic on the Model as possible,  
and only use the controller for grabbing the data that the View needs.  
In this case, your controller needs to know if it should tell the view  
to ask a question. You should let the model take care of the how and  
why. It’s not necessarily a Rails specific design pattern, more than it  
is considered best practice.

On a side note, I’m a fan of using the before\_filter to do a little  
pre-processing before hitting the code in the action. For example in  
your Entity controller:

before\_filter :check\_for\_client, :only =\> :edit

def edit  
#stuff related to editing an entity  
end

private  
def check\_for\_client  
@entity = Entity.find(params[:id])  
redirect\_to(new\_client\_path) unless @entity.has\_client?  
end

In addition to performing you check, your entity record is already  
loaded for your edit action.

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 20, 2008, 3:07pm UTC](https://www.ruby-forum.com/t/mvc-design-question-dependent-objects/132403/3 "2008-03-20T15:07:52Z")

</div>

Bryan M. wrote:

> On a side note, I’m a fan of using the before\_filter to do a little  
> pre-processing before hitting the code in the action. For example in  
> your Entity controller:
> 
> before\_filter :check\_for\_client, :only =\> :edit
> 
> def edit  
> #stuff related to editing an entity  
> end
> 
> private  
> def check\_for\_client  
> @entity = Entity.find(params[:id])  
> redirect\_to(new\_client\_path) unless @entity.has\_client?  
> end

I just want to clarify something. When one references the entity through  
the client new action then this code must go into the  
clients\_controller.rb correct? I understand that controllers are never  
implicitly invoked by reference to the model. Am I correct?

If this code is used in multiple controllers then is it best to extract  
it as a helper method or is there a different preferred way of doing  
that?

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 21, 2008, 4:06am UTC](https://www.ruby-forum.com/t/mvc-design-question-dependent-objects/132403/4 "2008-03-21T04:06:20Z")

</div>

> If this code is used in multiple controllers then is it best to  
> extract  
> it as a helper method or is there a different preferred way of doing  
> that?

Helpers are really meant to help automate view components. If you want  
to share some common functionality to your controllers, I would put that  
code into a module, and save it in the “lib” folder. You can then  
include that in your controllers (or models, or views) by just adding  
“include MyModule” to the controllers you want it accessible to. If you  
think it should be accessible to all your controllers, you can add the  
include statement to your ApplicationController.

I would say only use a module if it’s really necessary to share code.  
Typically, you’ll want to keep your CRUD operations inside of the  
controller. You’re right that models shouldn’t invoke the controller,  
but I think you’re forgetting that the Entity model and the Client model  
are already connected through their relationship.

In your Client Controller, you should have no trouble accessing it’s  
Entity through @client.entity, and vice versa in the Entity Controller  
(@entity.client).

So from the previous example, if you go to edit an Entity with no  
client, it redirects to the Client’s new action, where you ask a user if  
he’d like to add a client. Your client controller might look something  
like this:

before\_filter :load\_entity

def new  
@client = Client.new  
end

def create  
@client = Client.new(params[:client])  
@client.entity = @entity  
@client.save!  
end

private  
def load\_entity  
#since this is a has\_one, we can load the entity in for the whole  
controller  
@entity = Entity.find(params[:entity\_id])  
end

You’ll have to be passing the :entity\_id in from somewhere. You can do  
this in your re-directs:

redirect\_to(new\_client\_path, :entity\_id =\> @entity.id)

or if you’re using nested routes:

redirect\_to(new\_entity\_client\_path(@entity))

Hope this helps.
