Ruby on Rails: new vs. create vs. build difference

27
Oct
2

Difference by examples. Let’s say that a User has_many Blogs and a Blog belongs_to a User.

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-linux]
$ rails -v
Rails 2.3.4

Last updated: 27.10.2009

new

New objects can be instantiated as either empty (pass no construction parameter) or pre-set with attributes but not yet saved (pass a hash with key names matching the associated table column names). In both instances, valid attribute keys are determined by the column names of the associated table — hence you can‘t have attributes that aren‘t part of the table columns.

Model.new

Requires additional save to save to database.

>> b = Blog.new({:title => "Test"})
+-------+---------+------------+------------+
| title | user_id | created_at | updated_at |
+-------+---------+------------+------------+
| Test  | 1       |            |            |
+-------+---------+------------+------------+
1 row in set
>> b.save
  SQL (0.1ms)   BEGIN
  Blog Create (0.3ms)   INSERT INTO `blogs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES('2009-10-27 04:35:20', 'Test', '2009-10-27 04:35:20', 1)
  SQL (1.9ms)   COMMIT
=> true

New and associating through <<

The object is saved to the database after adding the association using <<.

>> u = User.first
>> b = Blog.new({:title => "Test"})
+-------+---------+------------+------------+
| title | user_id | created_at | updated_at |
+-------+---------+------------+------------+
| Test  | 1       |            |            |
+-------+---------+------------+------------+
1 row in set
>> u.blogs << b
  SQL (0.1ms)   BEGIN
  Blog Create (0.4ms)   INSERT INTO `blogs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES('2009-10-27 04:41:15', 'Test', '2009-10-27 04:41:15', 1)
  SQL (11.6ms)   COMMIT
  Blog Load (0.4ms)   SELECT * FROM `blogs` WHERE (`blogs`.user_id = 1)
+----+---------+---------+---------+---------+
| id | title   | user_id | crea... | upda... |
+----+---------+---------+---------+---------+
| 6  | Test    | 1       | 2009... | 2009... |
+----+---------+---------+---------+---------+
1 row in set

Calling new on an association

When calling new on an association, it will create the object with the foregin key correctly set, but will not save it to the database (not even when parent is saved). The created object must be saved manually with save.

>> u = User.first
>> b = u.blogs.new({:title => "Test"})
+-------+---------+------------+------------+
| title | user_id | created_at | updated_at |
+-------+---------+------------+------------+
| Test  | 1       |            |            |
+-------+---------+------------+------------+
1 row in set
>> u.save
  SQL (0.1ms)   BEGIN
  SQL (0.2ms)   COMMIT
=> true
>> u.blogs.all
  Blog Load (0.1ms)   SELECT * FROM `blogs` WHERE (`blogs`.user_id = 1)
0 rows in set
>> b.save
  SQL (0.1ms)   BEGIN
  Blog Create (0.3ms)   INSERT INTO `blogs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES('2009-10-27 04:54:06', 'Test', '2009-10-27 04:54:06', 1)
  SQL (3.9ms)   COMMIT
=> true
>> u.blogs.all
  Blog Load (0.3ms)   SELECT * FROM `blogs` WHERE (`blogs`.user_id = 1)
+----+---------+---------+---------+---------+
| id | title   | user_id | crea... | upda... |
+----+---------+---------+---------+---------+
| 7  | Test    | 1       | 2009... | 2009... |
+----+---------+---------+---------+---------+
1 row in set

Build

build(associations, parent = nil)

Model.build

Build cannot be called directly on the model. It can only be called on associations.

>> Blog.build({:title => "Test"})
NoMethodError:   SQL (9.0ms)   SHOW TABLES
undefined method `build' for #

Calling build on an association

When calling build on an association, the new object will be saved when the parent is saved.

>> u = User.first
>> u.blogs.build({:title => "Test"})
+-------+---------+------------+------------+
| title | user_id | created_at | updated_at |
+-------+---------+------------+------------+
| Test  | 1       |            |            |
+-------+---------+------------+------------+
1 row in set
>> u.save
  SQL (0.1ms)   BEGIN
  Blog Create (0.3ms)   INSERT INTO `blogs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES('2009-10-27 04:56:10', 'Test', '2009-10-27 04:56:10', 1)
  SQL (2.6ms)   COMMIT
=> true
>> u.blogs.all
  Blog Load (0.3ms)   SELECT * FROM `blogs` WHERE (`blogs`.user_id = 1)
+----+---------+---------+---------+---------+
| id | title   | user_id | crea... | upda... |
+----+---------+---------+---------+---------+
| 7  | Test    | 1       | 2009... | 2009... |
+----+---------+---------+---------+---------+
1 row in set

Create

Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

Model.create

As the description of the method says, the object will be saved to the database if it passes validations.

>> u = User.first
>> Blog.create({:title => "Test"})
  SQL (0.1ms)   BEGIN
  Blog Create (0.3ms)   INSERT INTO `blogs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES('2009-10-27 05:06:55', 'Test', '2009-10-27 05:06:55', NULL)
  SQL (10.7ms)   COMMIT
+----+-------+---------+-----------+-----------+
| id | title | user_id | create... | update... |
+----+-------+---------+-----------+-----------+
| 9  | Test  |         | 2009-1... | 2009-1... |
+----+-------+---------+-----------+-----------+
1 row in set
>> Blog.all
  Blog Load (0.3ms)   SELECT * FROM `blogs`
+----+-------+---------+-----------+-----------+
| id | title | user_id | create... | update... |
+----+-------+---------+-----------+-----------+
| 9  | Test  |         | 2009-1... | 2009-1... |
+----+-------+---------+-----------+-----------+
1 row in set

Note: In this case, there is no validation that the user_id field must be present, so such an object passes validation. If validation was added for user_id, the row would not be created in this case, because the object would not have passed validation. In that case, :user_id would have to be explicitly passed in the attrbiutes hash.

Calling create on an association

Works similar to build in this case (automatically adds the foregin_key - user_id in this case), but the new row is saved to the database already, and not only after the parent model is saved (as is the case with build).

>> u = User.first
>> u.blogs.create({:title => "Test"})
  SQL (0.1ms)   BEGIN
  Blog Create (0.3ms)   INSERT INTO `blogs` (`created_at`, `title`, `updated_at`, `user_id`) VALUES('2009-10-27 05:11:22', 'Test', '2009-10-27 05:11:22', 1)
  SQL (0.7ms)   COMMIT
+----+-------+---------+-----------+-----------+
| id | title | user_id | create... | update... |
+----+-------+---------+-----------+-----------+
| 10 | Test  |         | 2009-1... | 2009-1... |
+----+-------+---------+-----------+-----------+
1 row in set
>> u.blogs.all
  Blog Load (0.3ms)   SELECT * FROM `blogs` WHERE (`blogs`.user_id = 1)
+----+-------+---------+-----------+-----------+
| id | title | user_id | create... | update... |
+----+-------+---------+-----------+-----------+
| 10 | Test  |         | 2009-1... | 2009-1... |
+----+-------+---------+-----------+-----------+
1 row in set
>> u.save
  SQL (0.1ms)   BEGIN
  SQL (0.2ms)   COMMIT
=> true

Cheat cheet

Steps required for the object to be saved to database.

New

  • Blog.new(…).save
  • user.blogs << Blog.new(…)
  • user.blogs.new(…).save – do not use, no practical use case

Build

  • Blog.build – not possible
  • user.blogs.build(…), user.save – both are required to save to DB

Create

  • Blog.create(…)
  • user.blogs.create(…)

Ucenje na FRI

5
Sep
3

Ok, da vam povem kako se je treba učit na FRIju. Postopek je različen za praktični del izpita in teoretični del.

Prakticni del

Za učenje se rabi praviloma vedno 2 dni (velja za vse predmete v prvem in drugem letniku).

Prvi dan

Prvi dan si samo prebereš (enkrat, lahko pa tudi dvakrat) vse kar obsega predmet. To prebereš na tak način kot da bi bral knjigo, ne kot da bi se učil – pač probaš se delat da te zadeva ful zanima, ampak se ne ustavljaš sproti ali si probaš kaj zapomnit. Je pa pomembno da v tej fazi vsaj približno začneš razumet snov (to je v bistvu ena od poant tega). Če prideš do kakšnih težko prebavljivih delov (npr. veliko enih podatkov ki jih je težko brat, da ti pade koncentracija…), ta del lahko mirno preskočiš. Poanta tega branja je samo da okvirno veš za kaj se gre, pa kje v literaturi najt določeno stvar (pomembno za naslednji dan). To branje si probaš razporedit čez cel dan, in vmes si delaš pavze, ki so lahko poljubno dolge (pač odvisno od količine). Ko greš spat lahko še mal razmisliš o tem - med spanjem se ti potem vse skupaj malo utrdi. Pomembno je da greš čez vse v enem dnevu!

Drugi dan

Cilj drugega dneva je, da se naučiš tisto kar se ponavadi zahteva. Sta dve verziji tega dneva – ena vsebuje čez noč spanje ena pa ne. Uporaba je odvisna od količine stvari ki se jih ponavadi zahteva. Za drugi način je pomembno da se naspimo v prehodu iz prvega v drugi dan (vsaj 12 ur) – spanje je treba potegnit čim dlje (recimo idealno je nekje do 3eh popoldan) in pa je možen predvsem če je izpit dopoldan. V tem načinu je tudi priporočljiva primerna hidracija z vsaj 2L coca-cole ali energijske pijače (načeloma je coca-cola OK). Sicer potekata oba načina podobno.

Zdaj je izjemno pomembno naredit The List. To ne pomeni naredit celega portfolia, tako kot to delajo nekatere punce. To pomeni en list, ki ga imaš ponavadi lahko tudi na izpitu (sicer se ga moraš naučit na pamet). Najprej greš čez vse rešene naloge/izpite/kolokvije in si izpišeš ven vse enačbe in si malo pogledaš naloge. Pazit moraš da si ne pišeš na list nekih brezveznih stvari, za katere je samo 1% možnost da jih boš rabil – ponavadi so naloge vedno podobne in maš samo ene par enačb ki jih res rabiš. In seveda ne pišeš tistih stvari ki jih že itak znaš. Tukaj tudi pomaga če znaš kaj izpeljat (torej si ne napišeš), ker to implicitno pomeni da tudi razumeš. V bistvu tudi v tej fazi ni potrebno kaj preveč učenja, ampak si moraš lepo razporedit enačbe (približno zdaj veš kam kaj spada ker si prejšnji dan prebral snov). Zdaj pa je še en pomemben korak. Zdaj moraš še enkrat čez snov v knjigi, ampak jo zdaj ne bereš ampak jo samo preletiš in predvsem iščeš kakšne enačbe oz. vse kar se nanaša na praktične naloge (ponavadi mogoče 10% snovi). Te stvari si izpišeš na en pomožen list in jih kasneje prepišeš na The List (tisto kar misliš da se rabi). Če so samo enačbe lahko tudi direktno na The List. Ta korak je zelo pomemben, ker tukaj izpolniš še tisto luknjo, ki jo nisi zapolnil z starimi izpiti (ponavadi je vedno kakšen minimalno nov štos). V tem koraku moraš velikokrat prepisat kakšne stvari iz tistih “težko prebavljivih delov” ki sem jih omenil pri prvem dnevu.

No in ko maš enkrat ta list je v bistvu to to. Zdej si okol 50% (rezultat), potem pa greš čez tiste naloge iz kjer si izpisal te enačbe in jih probaš sam rešit. Oziroma prvih par nalog lahko kar samo pogledaš rešitev in pač poštekaš kako se pride do te rešitve, potem pa ene par nalog še sam rešiš in to je to. Lahko greš tudi še čez list in se prepričaš da za vse enačbe veš približno kje se uporabljajo. Če kakšne enačbe ne zastopiš je zelo pametno pogledat v literaturo – kakšnih pa se preprosto ne da zastopit tako da se nima smisla trudit (ampak redko)… Učit se samo polovico stvari (v smislu da bo to dovolj za 50%) se ne splača – bolj se splača slabo naučit vse. Lahko pa včasih spustiš kakšen manjši zelo zakompliciran del, ki se ne pojavi vedno ali pa je vreden malo točk – po občutku…

Pri praktičnem delu je torej glavno da približno zastopiš snov in da imaš na listu vse osnovne enačbe ki jih rabiš. Zelo pametno je tudi da te enačbe razumeš (to je v bistvu edini del ki bi ga lahko smatral kot učenje tukaj).

 

Teoretični del pa drugič :) Teoretični del lahko traja od 1-4 dni.

Potopis Ljubljana – Prevoje

22
Jun
2

Danes je bil že čas za vsakoletni tradicionalni dogodek Kosilo’09.

Začeli smo pri mostu čez Ljubljanico, z vestnim in zbranim voznikom Cvetkotom.

DSC07798

Na poti smo pobrali še nekaj brhkih deklet:

DSC07802

Kot je v tradiciji smo Pr’Gašperju v Prevojah tudi letos naleteli na zaprta vrata.

DSC07804

In seveda smo tradicionalno pristali v gostilni Pri Čebelici.DSC07805

Eni bolj veseli kot drugi…

DSC07807 DSC07808

Potem se je h nam prisedla še ena gospa v zeleni obleki, ki je nihče ni poznal.

DSC07810

Sledil je zdrav obrok, neke ribe in svinjski zrezek v gobovi omaki, ki je žal prehitro izginil da bi ga lahko slikal. Riba je bila očitno bolj zanič zato sem uspel dobit tale posnetek:

DSC07814 Nato pa še tradicionalna sladica z medom (pač čebelarsko društvo…). Na koncu žal nisem ujel, ko je šef gostilne sedel kar v prtljažnik avtomobila svojega kolega, potem pa so se odpeljali.

DSC07816 In pa še nekaj random fotk:

DSC07839

DSC07817

Vlakec!

DSC07829

Tokio Hotel – Monsoon; Rock Band FC 100% Expert :P

22
Jun
0

22062009034

Chew on that :P

Through the Monsoon

18
Jun
0

Najboljsi moj rezultat do zdaj v Rock Bandu :P

18062009033

Še mal pa bo FC :)

Komad (live):

Intermezzo

3
Jun
5

Ne vem če sem prav napisal, je pa že čas da kaj dodam… No, najprej eno vprašanje: A ima kdo veliko DLC materiala za Rock Band ali Guitar Hero (dodatni komadi na Xbox 360)? Ali pa če kdo ve za način, kako dobit to z neta (zaenkrat še nisem našel načina)? Če kdo ima, naj bi se dalo skopirat, pa se lahko kaj zmenimo :)

Sicer pa, gužva na faksu, eno manjše spoznanje: Windows XP še ne podpira AES enkripcije (šele Vista), kar posledično pomeni da tudi .NET ne podpira AES enkripcije na Windows XP. Bummer. Na koncu sem nerade volje uporabil Javo, ki ima svoje libraryje.

Kar dogaja u lajfu zdej – več al manj faks, danes kolokvij, pojutrišnem 2 zagovora in kolokvij (btw pri nas so lahko kolokviji namesto izpita). En kolega je že skoraj pobegnil na VSŠ, v bistvu se bolj resno drživa na UNI samo še dva. Manjka mi še 13 kreditnih točk, kar pomeni, da moram narest samo še 2 predmeta, kar je super :) No v najslabšem primeru 3. Potem pa upajmo, da je 3. letnik nekoliko lažji, da si končno malo odpočijem.

Aja skoraj bi pozabil slikco:

funny-cat

Posted under Social, Stuff

Xbox 360 HDMI to DVI and audio (jack)

29
May
10

Updated version

Preface

Well, a friend bought an Xbox 360 and previously also bought a HDMI to DVI adapter for it. The thing is, the HDMI to DVI adapter only provides the video, but not the audio. You get an adapter with Xbox 360 which has audio cinch connectors, but it’s so big that when you plug in the DVI cable, you can’t plug in this adapter as well, even though it has a separate connector on the Xbox 360. I feel Xbox 360 not having a stand-alone stereo output connector is kind of silly by the way.

I had this genius idea to break the big connector apart so it could fit in together with the HDMI connector plugged in. It actually worked :) So, yes, even though Microsoft made that big connector which seems to look like “hey, you can only plug in either HDMI or this thing”, you can actually plug in both and get video from HDMI and sound from their proprietary adapter. It’s probably mostly a marketing trick if you ask me (they try to force you to buy another adapter from them).

What you need

  • A (male) HDMI to (male) DVI cable or adapter (for the video) – sadly, there is no way around this. I recommend a cable instead of an adapter (with an adapter you need also a HDMI cable and/or a DVI cable – depends on adapter type).
  • A cinch (also called RCA, red/white) to jack (stereo, like headphones, for the audio) adapter (cheap and available in most electronics or audio stores) or speakers with cinch inputs – then you don’t need the adapter. Basically, you need an adapter that has female cinch on one end and the other end needs to be such that you can plug in your speakers. Usually that means female jack (that kind of adapter is hard to find), but some (like surround) speakers usually have a female jack input (like mic input on PC). In such a case, the adapter is the easiest to find, female cinch to male jack. In case you can’t plug in a male jack into your speakers, your best bet is to still buy a female cinch to male jack adapter and then a female jack to female jack adapter or (extension) cable, which is much easier to find than a female cinch to female jack adapter.
  • Scissors
  • Sharp cutting tool such as sharp pliers/pincers
  • (optional) duct tape or insulation tape

You can see some examples of the adapters you might want below (you will probably want the first and second one):

Price

Assuming you already have the scissors and pliers (and you could probably improvise anyway if you don’t), in my local store the HDMI to DVI cable costed about 5-10€ and the cinch to jack adapter costed about 5€. However you can find them much cheaper online. If you’re in a big country try Ebay, otherwise if you can wait like 14 days for shipping, you can buy from DealExtreme (free shipping anywhere in the world!):

Total price: around $8, which is around 6€. In a local store, however, expect to pay around 10-15€.

If you already have these adapters (there’s a good chance you have the audio one), then, of course, it’s free for you. You also might need these adapters in the future, so it’s a good investment.

How to do it

You have to break apart the composite connector’s casing. It took me a while to figure out how to do it, so here is how I did it:

  • use scissors to cut the rubber around the cable entering the big connector (the connector that plugs into Xbox 360 below the HDMI connector).
  • use a screwdriver and try to “pull” as much rubber as you can out of the connector (just shove the screwdriver into the connector through the hole of the cable, press on the rubber and try to pull it out). do this until you clear enough rubber so you can see a bit into the connector.
  • now you can use some scissor like (sharp) pliers (pincers) and try to cut and bend the top plastic part of the connector. after I cut a little piece from the left side I was able to just pull the whole top plastic part off (it’s only glued to the bottom part so after you get a good grip it comes off quite easily).
  • you can now remove all the plastic that surrounds the connector, and optionally wrap the whole connector in 1 layer of duct tape (for insulation).

If your Xbox 360 and the connector were anything like the one I used, then you can now plug in both the HDMI connector and the Microsoft’s connector. If you have a big HDMI connector you may have to do the same thing for it as well (remove the casing). This kind of setup works very well when you’re connecting Xbox 360 to an LCD monitor with a DVI input and use some kind of speakers for sound. However, like I mentioned, the Microsoft’s cable has two male cinch connectors for sound (white and red), so you will probably need to use some kind of an adapter to a jack connector, or whatever your speakers plug into.

This may also let you get two video outputs (haven’t tried this though) – one through HDMI and one through Microsoft’s adapter (VHS yellow cinch output).

DSC00212
This is a (low quality) image of how both cables look plugged into the Xbox 360. I only removed the top part of the connector’s plastic casing.

Things I love about Google Chrome

28
May
4

google-chrome-dark-theme (when i was searching for a pic to use with this post, I realized Chrome supported skins, which I haven’t known until now)

  1. It’s SO fast Firefox can just hide in its little corner.
  2. I love how they placed the tabs into the titlebar, it just saves so much space and is rarely problematic.
  3. You can just drag a tab out of the window and make it its own window. It comes handy sometimes.
  4. Open in new tab is the first item in the right click context menu, unlike Firefox where it’s second (after Open in new window). I think the placement is just superior in Chrome.
  5. Why have a bookmarks menu when you can just list the bookmarks at the end of the Bookmarks toolbar? It’s just genious how they managed to save so much space on such simple things. After you start using it, you start wondering why all other browsers don’t follow this design.
  6. There is no search input box, you just enter the search query into the address bar instead. Firefox has something like this but it sucks and it’s slow as hell. I do admit, however, that sometimes it sucks that Chrome tries to auto-complete what you type in into an address, so you have to press delete before enter to search for it. But this leads me to point nr. 7.
  7. Just enter the first few letters of the URL, and if you’ve visited it before, Chrome will auto-complete it with the most probable match. Just press enter to browse to the site – unlike Firefox where you’ll have to press the down key first. Why??!

Of course there are some things I do not like about Chrome, but I can live with them mostly because Firefox is so damn slow:

  1. No extension support.
  2. No support for client SSL certificates (like for banking).
  3. Not supported on Linux yet, which is a bit of a downside, but not so much for me. You can always use Opera on Linux, it’s still much faster than Firefox :P
  4. JavaScript error console like in Firefox?? Can’t find something like that, so I still have to debug all my JS code in Firefox…

PS: This isn’t really a feature I use often, but I think Chrome was the first browser to support the “incognito mode”. It’s a mode where no history or cookies are saved (useful for porn, he he).

What do you think about Chrome? Are you still using Firefox, and are you thinking of switching to another browser? I appreciate your input.

Avant Browser

28
May
0

Avant browser je nov spletni brskalnik (kot npr. Internet Explorer ali Mozilla Firefox). Všeč mi je slogan “The Fastest Web Browser on Earth”, me pa zanima če je to res. Če ima kdo kakšne izkušnje naj sporoči, Mozilla Firefox je namreč obupno počasna in sem jo že zamenjal z Google Chrome, vendar bi poskusil tudi tale Avant, če je kaj za kaj. Komentirajte.

Avant-Browser-1-1.5-RC1_1

PS: Ni mi všeč da uporablja Yahoo! za default search engine :S

Bowling FRI

28
May
2

Danes je ŠOFRI organiziral bowling za FRIjevce. Na žalost sem prišel šele kasneje in nisem igral. Od znancev, ki so igrali, je bil daleč najboljši Jure Ham. Vse skupaj se je odvijalo v BTC Areni (poleg Koloseja). Če je komu uspelo izvesti “strike” 3x zapored, je dobil žirafo (veliko piva :) ). Uspelo je kar 4im, potem pa je ŠOFRIju očitno zmanjkalo denarja :P Nam na žalost ni uspelo, je pa Hamu uspelo 2x zapored :)

Dve (slabši) slikci:

27052009029 27052009030

Btw tisto na mizi v resnici niso anal-plugi, ampak podložki za žirafe.

Posted under Social