# Add external data at new record creation time

**URL:** <https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041>\
**Category:** Rails\
**Created:** [January 4, 2010, 11:24am UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041 "2010-01-04T11:24:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![qaswm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/5f8ce5/32.png) [@qaswm](https://www.ruby-forum.com/u/qaswm)\
**Post date:** [January 4, 2010, 11:24am UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041/1 "2010-01-04T11:24:22Z")

</div>

In my project i require a bit.ly link for each new product entered in  
the database. Please guide me on how to do this?

Note: I am using a standard rails app with basic actions to test this  
code

I plan on writing a helper function which will be able to take the id  
for the new record and return the link.

Here are my questions:

1. Should I add the link column in the same table as the product or  
create a new table with just a vehicle id and its corresponding bit.ly  
link?

2. Where in the controller should i make the call to create the link as  
a product id will be required before the link can be generated and I am  
not 100% sure where exactly in the controller when creating a new record  
is the new record id available to be accessed.

Apologies in advance if the questions is not very clear but any help  
will be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![qaswm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/5f8ce5/32.png) [@qaswm](https://www.ruby-forum.com/u/qaswm)\
**Post date:** [January 4, 2010, 1:49pm UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041/2 "2010-01-04T13:49:05Z")

</div>

Quee WM wrote:

> I plan on writing a helper function which will be able to take the id  
> for the new record and return the link.

Using a “helper” function implies that the coding will trigger as the  
template is being rendered. If this is the case, you don’t need an entry  
in the database. Just write the helper to use the item id to look up the  
item and generate the link from the item information.

However, if the link/URL is needed elsewhere (perhaps outside the Rails  
app) and therefore needs to be stored in the database, then I’d suggest  
you just create an extra field (bit\_ly\_url perhaps). This is assuming  
that each vehicle has a unique URL.

As for the code that generates the URL - I’d create a custom ruby class  
to do that. Put the code in the lib folder.

So for example, say you create a class CreateURL with a class method of  
bit\_ly\_for\_vehicle, you can then create a vehicle instance method to  
call the CreateURL method and this can be triggered via a call back  
(e.g. before\_save)

So

class Vehicle \< ActiveRecord::Base  
before\_save update\_bit\_ly\_url

def update\_bit\_ly\_url  
bit\_ly\_url = CreateURL.bit\_ly\_for\_vehicle(self.id)  
end  
end

---

<div class="post-metadata">

**Author:** ![qaswm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/5f8ce5/32.png) [@qaswm](https://www.ruby-forum.com/u/qaswm)\
**Post date:** [January 4, 2010, 1:52pm UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041/3 "2010-01-04T13:52:33Z")

</div>

Rob N. wrote:

> class Vehicle \< ActiveRecord::Base  
> before\_save update\_bit\_ly\_url
> 
> def update\_bit\_ly\_url  
> bit\_ly\_url = CreateURL.bit\_ly\_for\_vehicle(self.id)  
> end  
> end

Actually - just spotted that you’d have to use after\_save or information  
other than the id to generate the url, as on create, the id doesn’t  
exist until the object is saved. Also CreateUrl is probably a better  
ruby class name.

---

<div class="post-metadata">

**Author:** ![qaswm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/5f8ce5/32.png) [@qaswm](https://www.ruby-forum.com/u/qaswm)\
**Post date:** [January 4, 2010, 9:19pm UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041/4 "2010-01-04T21:19:53Z")

</div>

Thanks for the help. That put me on the right path.

---

<div class="post-metadata">

**Author:** ![qaswm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/5f8ce5/32.png) [@qaswm](https://www.ruby-forum.com/u/qaswm)\
**Post date:** [January 5, 2010, 10:29am UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041/5 "2010-01-05T10:29:57Z")

</div>

Back for some more help.

I added the following code to the model of the vehicle

class Vehicle \< ActiveRecord::Base  
after\_save :update\_bit\_ly\_url

def update\_bit\_ly\_url  
bit\_ly\_url = CreateUri::bit\_ly\_for\_vehicle(self.id)  
puts bit\_ly\_url  
end  
end

had to change CreateUri. to CreateUri:: as it was not recognizing  
CreateUri.

maybe I have not written the class properly or have not included it in  
the correct manner.

Now this is the error i get.

NameError (uninitialized constant Vehicle::CreateUri):  
app/models/vehicle.rb:22:in `update_bit_ly_url' app/controllers/vehicles_controller.rb:46:in`create’

Any ideas?

---

<div class="post-metadata">

**Author:** ![qaswm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/q/5f8ce5/32.png) [@qaswm](https://www.ruby-forum.com/u/qaswm)\
**Post date:** [January 5, 2010, 8:19pm UTC](https://www.ruby-forum.com/t/add-external-data-at-new-record-creation-time/181041/6 "2010-01-05T20:19:21Z")

</div>

Your change from . to :: is a red herring. The method call semantics  
of . and :: are the same. The error means that your CreateUri class is  
not being loaded. Check the way it is loaded (by Rails autoloading, by  
a require statement, etc).

Also, I would have structured the url creation class differently.  
First, CreateUri is a poor class name because it is too generic.  
Second, passing an integer (the vehicle id) would require the  
CreateUri class to know far too much about what that integer  
represents, thus coupling it conceptually to the Vehicle class. These  
problems are apparent in the need for the awkward method name  
“bit\_ly\_for\_vehicle”. The Bitly url generator should accept a url and  
return a url, as this is the interface provided by the service itself  
(bit.ly’s API).

Given that the Bitly API requires authentication, I would prefer  
something like:

Bitly.new(username, api\_token).shorten(url\_for(@vehicle)).short\_url

“Shorten the url for the vehicle” reveals the code’s intention nicely.

In fact, and speaking of reuse, this is precisely what the Bitly gem  
provides ([GitHub - philnash/bitly: 🗜 A Ruby wrapper for the bit.ly API](http://github.com/philnash/bitly)).

This does not address performance and reliability concerns with the  
network, the Bitly service and etc., but it is at least a good start.  
Also, do note that this will require url\_for in your model. Google  
should tell you how to make this happen.

On Jan 5, 1:29Â am, Quee WM [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Â end  
> NameError (uninitialized constant Vehicle::CreateUri):  
> Â app/models/vehicle.rb:22:in `update_bit_ly_url' Â app/controllers/vehicles_controller.rb:46:in `create’
> 
> ## Any ideas?
> 
> Posted viahttp://www.ruby-forum.com/.

Rein H.  
[http://reinh.com](http://reinh.com) | [http://reductivelabs.com](http://reductivelabs.com)
