Di Wu
Di Wu

Reputation: 6448

Ruby on Rails syntax question

I'm a super newbie in RoR. Right now I'm working on this interesting Rails for Zombies exercises. And I got stuck with some syntax questions...

My code to this is:

Weapon.where(:zombie => "Ash")

But it won't work. If instead I typed:

Weapon.find(1)

I passed (since the first weapon belongs to the zombie Ash anyway).

My question is, what's wrong with my answer with this .where() method?

Thanks in advance.

alt text

alt text

alt text

Upvotes: 5

Views: 2979

Answers (14)

Azmir Shah
Azmir Shah

Reputation: 1

the answers is Zombie.find(1).weapons .. then you will success to find all Ash's weapons.

Upvotes: 0

Reee
Reee

Reputation: 195

I came across the same problem today but the accepted answer didn't work for me. I don't know whether the API has changed since 2010 but I got it to work by doing this:

Weapon.joi­ns(:zombie­).where(:z­ombies => {:nam­e => "Ash"­})

You can also get the same result by joining in the other direction although I think the first solution is what the question was looking for:

Zombie.whe­re(:name => 'Ash'­).first.we­apons

Upvotes: 2

Oscar Marin
Oscar Marin

Reputation: 11

Weapon.whe­re(:zombie­_id => Zombi­e.where(:n­ame => "Ash"­))

You can select from DB Weapon, the zombie_id which name is Ash from DB Zombie.

Upvotes: 1

Gerry
Gerry

Reputation: 11154

If, like me, you were trying to attempt this via the Zombie Model, you will need to use first method. This is because where() returns a collection of Zombies.

i.e.

Zombie.where(:name => "Ash").first.weapons

This tutorial still teaches the old hash syntax, but ever since Ruby 1.9 you can (and should) use the new simplified format. This syntax even works in the Zombies tutorial:

Zombie.where(name:"Ash").first.weapons

Upvotes: 4

Nikita Hismatov
Nikita Hismatov

Reputation: 1656

Zombie.where(:name => "Ash").first.weapons

IMHO: I think that this way is more explicit: first, we are looking for a zombie, and then - want to take the first one's weapon.

Surely, you can look for the Weapon by zombie's id (Weapon.where(:zombie_id => SOME_ZOMBIE_ID)), BUT as for me - this is not the thing I want to see in my code half a year after - it is about more coding and wasting more time for understanding.

ps: Seems that my answer is a shorter version of Gerry's answer (see above) - sorry for that :)

Upvotes: 1

Brett
Brett

Reputation: 558

I think you passed using Weapon.find(1) because there was only one weapon in the weapons table, but if you create another weapon, with the :id => 1 then your original syntax wouldn't work - cause it only returned the first weapon and not all the weapons.

I passed using, Zombie.find(1).weapons which will return multiple entries for weapons associated with :id = 1, but was also thinking the same as you and wanted to search by :name and not :id.

I was also thinking about using the "where" attribute, but can't get it to work - and when I used @edgerunner answer it returned:

#<ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: zombie.name: SELECT "weapons".* FROM "weapons" WHERE "zombie"."name" = 'Ash'>

so I'm not sure if this is a limitation through the program or what - as it is, im still bit confused.

Upvotes: 0

Russell Asher
Russell Asher

Reputation: 195

This is how they intend you to do it (based on the video)

ash = Zombie.find(1) ash.weapons

Which should return an array of all the weapons ash owns. I tried for so long to use the count method and then I realized they just wanted the actual weapon items (array/list/whatever it is I'm just starting rails from a c++ and python background)

Upvotes: 2

Henrique Silvestre
Henrique Silvestre

Reputation: 11

In this context u can try this code:

z = Zombie.find("ID")
Weapon.where(:zombie_id => z)

Upvotes: 1

danielvdotcom
danielvdotcom

Reputation: 11

Weapon.where(:zombie_id => '1') => [#]

Upvotes: 1

RsT
RsT

Reputation: 11

Since the zombie table is linked to the weapon table, you can use the following code: Zombie.find(1).weapons.all

FYI - Zombie ID 1 = Ash

Upvotes: 1

Rod
Rod

Reputation: 421

If you want a where clause you Now returns a single value then you could write

Zombie.where(:name => "ash").first

Upvotes: 3

edgerunner
edgerunner

Reputation: 14973

You should have nested the query as follows:

Weapon.where(:zombie => {:name => "Ash"})

That would give you the weapons that belong to the zombies whose names are 'Ash'

Upvotes: 7

ranendra
ranendra

Reputation: 2512

You generally use Model.find( ) if a single object is needed and it returns nil if not found. Whereas Model.where({:field => value}) returns an array of objects those matches the condition.

Upvotes: 2

Chris Kimpton
Chris Kimpton

Reputation: 5541

Not sure, also new to Rails3 queries, but doesnt :zombie expect to match a zombie object, not its name.

I would do Zombie.where(:name => "Ash").weapons

Upvotes: 2

Related Questions