# Wiring a dependent update

**URL:** <https://www.ruby-forum.com/t/wiring-a-dependent-update/131848>\
**Category:** Rails\
**Created:** [March 13, 2008, 7:39pm UTC](https://www.ruby-forum.com/t/wiring-a-dependent-update/131848 "2008-03-13T19:39:23Z")\
**Posts on this page:** 3\
**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 13, 2008, 7:39pm UTC](https://www.ruby-forum.com/t/wiring-a-dependent-update/131848/1 "2008-03-13T19:39:23Z")

</div>

Rails 2.0.2  
Ruby 1.8.5  
SQLite3  
CentOS-5.1

models/

Entity  
entity has\_one client

Client  
client belongs\_to entity

validates\_associated

view/

clients/new.html.erb

# New client

\<%= error\_messages\_for :client %\>  
\<%= error\_messages\_for :entity %\>

\<% form\_for(@client) do |f| %\>

\<% fields\_for(@entity) do |e| %\>

**Client Name**  
  
\<%= e.text\_field :entity\_name %\>

```
<p>
  <b>Client Legal Name</b><br />
  <%= e.text_field :entity_legal_name %>
</p>

<p>
  <b>Client Legal Form</b><br />
  <%= e.text_field :entity_legal_form %>
</p>

```

\<% end %\>

**Client status**  
 \<%= f.text\_field :client\_status %\>

...

controllers/  
clients\_controller.rb

# POST /clients

# POST /clients.xml

def create  
@entity = Entity.new(params[:entity])  
@client = Client.new(params[:client])

```
respond_to do |format|
  if @entity.save && @client.save
    flash[:notice] = 'Client was successfully created.'
    format.html { redirect_to(@client) }
    format.xml { render :xml => @client, :status => :created,

```

:location =\> @client }  
else  
format.html { render :action =\> “new” }  
format.xml { render :xml =\> @client.errors, :status =\>  
:unprocessable\_entity }  
end  
end  
end

What I want to do is to have an entity created if one does not exist and  
the existing entity.id returned to client otherwise. The above code  
almost works when there is no existing entity but the client.entity\_id  
is not set to the id of the newly created entity throwing an SQL error.

Question 1. Must I create a method in clients.rb, say entity\_build, that  
checks for the existence of an entity (find\_by\_entity\_name) or creates a  
new entity otherwise? What would this look like?

Question 2. What do I pass the method from the controller? @entity,  
@client?

Question 3. How do I get the fields from the view into the entity from  
within the client model? See Q.2

Question 4. Is there a simpler way do do this?

I am twisting in the breeze her trying to figure out how to make this  
work. I have read any number of tutorials and code examples but I am  
just not getting it.

Any help is most welcome.

---

<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 14, 2008, 2:20am UTC](https://www.ruby-forum.com/t/wiring-a-dependent-update/131848/2 "2008-03-14T02:20:07Z")

</div>

Okay - I’ve never understood the has\_one principle. If :entity has\_one  
:client, then why wouldn’t you just put the fields for :client in the  
:entity model?

If it was :entity has\_many :clients, then the way you would get  
client.entity\_id populated would be as follows:

```
@entity = Entity.new(params[:entity])
@client = Client.new(params[:client])
@entity.clients << @client

```

The result of that last line is that the new client is updated with the  
appropriate entity\_id and then saved. So, in a has\_one maybe it’s like  
this…

```
@entity = Entity.new(params[:entity])
@client = Client.new(params[:client])
@entity.client = @client

```

But I’m just not sure - the has\_one thing is confusing to me, and from  
what I’ve read it actually works backwards from what you would expect if  
you’re used to has\_many.

Can you fill me in a little more on what you’re doing - I’m almost  
certain there’s a better design out there just waiting for you to find  
it. 🙂

---

<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 14, 2008, 4:06pm UTC](https://www.ruby-forum.com/t/wiring-a-dependent-update/131848/3 "2008-03-14T16:06:50Z")

</div>

Cayce B. wrote:

> Okay - I’ve never understood the has\_one principle. If :entity has\_one  
> :client, then why wouldn’t you just put the fields for :client in the  
> :entity model?

My background is data design and I am a newcomer to ruby and rails. I  
have examined both the language and framework on and off for the past  
few years but I am now beginning a real project. Currently, my main  
problem is getting enough traction with the API to know where to go to  
find answers. This is coming, albeit slowly.

Now, with respect to the has\_one / belongs\_to relationship or, as rails  
puts it, association; consider the situation at hand. What is a client?  
Well, that depends upon your point of view but essentially a client is  
someone that consumes your output and sends you money. Now, what is a  
vendor? Well, similarly a vendor is someone whose output you consume and  
whom you send money to. The salient question here is: are these two  
concepts, clients and vendors, separate things or are they separate  
roles of a single thing?

In many system designs these two concepts are treated as separate  
things. They possess state like account balance and physical attributes  
like addresses. They are related to transactions like invoices and  
cheques. However, considered another way, client and vendor can be  
profitably considered as just roles played by a distinct entity, whose  
existence is independent of whether or not they buy from or sell to us.

If one considers a client and a vendor simply as roles within a  
transaction based system then entity may be factored out and become a  
separate concept. A single entity may then possess the role of client  
(has\_one :client) or vendor (has\_one :vendor) (or both or neither) and  
also possess multiple attributes (has\_many :locations, has\_many  
:contacts). The role of client and vendor may not persist (client.status  
= “inactive”) even when the other role does (vendor.status =  
“preferred”). An entity may be something else than a client or a  
vendor, perhaps an employee, a consignee for a drop shipment, an agent  
for the firm, or a person working at a client. Perhaps it is  
significant to know whether two or more entities are related (has\_many  
:relationships).

Extracting the entity from its roles permits entity.contacts where  
contacts:

belongs\_to :entity, :foreign\_key =\> :entity\_id  
belongs\_to :entity, :foreign\_key =\> :contact\_entity\_id

You can now reflect into a single representation of entity properties  
located in a group of consistently named and structured tables whether  
the entity is considered a client or a vendor in context.

Given this you also can have things like shipments:

has\_many :orders, :through =\> :order\_shipments  
has\_one :entity, :foreign\_key =\> :consignee\_entity\_id,  
:include =\> [:locations, :contacts]  
has\_one :entity, :foreign\_key =\> :carrier\_entity\_id,  
…

You can also handle situations like issuing cheques to non-vendors  
(refunds to clients) and receiving funds from non-clients (employee  
reimbursement for disallowed expenses) in a much more natural manner  
since you are not required by the data design to set up a vendor in the  
first or a client in the second instance.

> If it was :entity has\_many :clients, then the way you would get  
> client.entity\_id populated would be as follows:
> 
> ```
> @entity = Entity.new(params[:entity])
> @client = Client.new(params[:client])
> @entity.clients << @client
> 
> ```

In my design an entity either has a role or it does not. A single entity  
is not treated as being multiple clients. In certain circumstances one  
might wish to treat divisions of a very large corporate entity as  
separate clients and this design could handle that eventuality, but that  
is not the case at present. On the other hand, if these division were  
structured as distinct legal forms then the current approach remains  
valid and a relationship model accommodates the reality.

> The result of that last line is that the new client is updated with the  
> appropriate entity\_id and then saved. So, in a has\_one maybe it’s like  
> this…
> 
> ```
> @entity = Entity.new(params[:entity])
> @client = Client.new(params[:client])
> @entity.client = @client
> 
> ```

This will fail with an SQL error as client.entity\_id will be null. I  
know, I’ve tried ;-).

> But I’m just not sure - the has\_one thing is confusing to me, and from  
> what I’ve read it actually works backwards from what you would expect if  
> you’re used to has\_many.

What is bedeviling me at the moment is my state of profound ignorance  
with the Rails APi. There is nothing else for it but to read the damn  
thing again but, as with many things, what you read at leisure seldom  
returns when you need it. I have since rediscovered the API for  
ActiveRecord::Associations::ClassMethods and have therein learned that  
the way to do what I want is eventually going to look somewhat like  
this:

In clients\_controllers.rb

# GET /clients/new

# GET /clients/new.xml

def new  
@entity = Entity.new  
@client = @entities.build\_client  
…

# POST /clients

# POST /clients.xml

def create  
@entity = Entity.new(params[:entity])  
@client = @entity.build\_client(params[:client])

Based on my very preliminary and presently shallow understanding, the  
build\_client method is generated by AR in consequence of the has\_one /  
belongs\_to association specification in the respective models. This  
then wires the underlying dependencies wherein client.entity\_id is set  
to entity.id. In this case the AR association also enforces the  
foreign\_key constraint so that if @entity.save fails then too does the  
dependent @client.save.

If I were to wrap this in a transaction  
(ActiveRecord::Transactions::ClassMethods) then it appears that I need  
to employ entity.save! and client.save! to force a transactional roll  
back in the event of an error in either. However, subject to further  
study and a deeper apprehension on my part, a transactional approach  
does not seem to provide any measurable benefit over the basic behaviour  
in this simple case.

Thank you for presenting the opportunity to clarify this to myself. It  
is amazing how having to explain oneself to someone else straightens  
things out in your own mind.
