Associations join

Hey there,

Im fairly new to rails and i’ve tried several tutorials which taught me
how to use the associatives on a basic level(has_many => belongs_to).

However i’m trying to figure out how i can create and execute some kind
of a join. My case is:
I’ve got a list of playing cards in my DB that are static.
Every user can have any of those cards, even multiple times. So my
tables would look something like this:

users
id = 1
name => “Bear Grylls”

id => 2
name => “Poopypants”

cards
id => 1
name => “Captain Carl”

id => 2
name => “Whatever”

usercardsjoin
card_id => 1
user_id => 1

card_id => 2
user_id=> 1

card_id => 1
user_id => 2

Although i know how it should look like because of my experience with
PHP i have absolutely no clue how i can get this one to work.

Can any of you explain this or send me a link which handles this
particular issue?

Thanks in advance,

Check out the guide to associations. It should have more information
than
you need…

Hey!

Associats are covered in great detail here:

I think what you need is a has_many :through association

– Manuel

I seem to have it up and running at this point. I made all the
has_many’s etc. in my models. But when i try @cards.user (Or each it
first and use c.user) it says ‘undefined method ‘user’’. So i’m assuming
i’m doing something awfully wrong.

My card_controller looks like this
def show
@cards = Card.all
end

Here are my models:
card.rb
class Card < ActiveRecord::Base
has_many :cardlevels
has_many :users, :through => :cardlevels
end

cardlevel.rb
class Cardlevel < ActiveRecord::Base
belongs_to :users
belongs_to :cards
end

user.rb
class User < ActiveRecord::Base
has_many :cardlevels
has_many :cards, :through => :cardlevels
end


On 19 June 2012 13:38, Timen E. [email protected] wrote:

class Cardlevel < ActiveRecord::Base
belongs_to :users
belongs_to :cards

Those should both be singular (:user and :card). Each cardlevel
belongs to one user and card so they should be singular.

Colin

Edit: Derp, i placed the associations in the controller instead of model

Colin L. wrote in post #1065209:

On 19 June 2012 13:38, Timen E. [email protected] wrote:

class Cardlevel < ActiveRecord::Base
belongs_to :users
belongs_to :cards

Those should both be singular (:user and :card). Each cardlevel
belongs to one user and card so they should be singular.

Colin

That sounds fair indeed, however when i tried i still got the same
error. This associations got me so bloody confused :')

On 20 June 2012 08:39, Timen E. [email protected] wrote:

Colin

That sounds fair indeed, however when i tried i still got the same
error. This associations got me so bloody confused :')

Post the code for the models, the code that generates the error (with
a few lines each side) and the full error message.

Colin

I’ve just got a really basic setup to see if i got it working:

card.rb
class Card < ActiveRecord::Base
attr_accessible :attack, :defense, :name
has_many :cardlevels
has_many :users, :through => :cardlevels
end

cardlevel.rb
class Cardlevel < ActiveRecord::Base
attr_accessible :card_id, :level, :user_id
belongs_to :user
belongs_to :card
end

user.rb
class User < ActiveRecord::Base
attr_accessible :name
has_many :cardlevels
has_many :cards
end

card_controller.rb
class CardController < ApplicationController
def show
@card = Card.all
end
end

User & cardlevel are empty for now

Card#show

Find me in app/views/card/show.html.erb

<%= @card.user %> Where i tried eaching the @card, tried @card.users, @card.user.name etc. etc. -----------------------------------------------------

The error:
Showing c:/tuts/kaartje/app/views/card/show.html.erb where line #3
raised:

undefined method `user’ for #Array:0x3c81ac8
Extracted source (around line #3):

1:

Card#show


2:

Find me in app/views/card/show.html.erb


3: <%= @card.user %>
Rails.root: c:/tuts/kaartje

Application Trace | Framework Trace | Full Trace
app/views/card/show.html.erb:3:in
`_app_views_card_show_html_erb___1042037435_30519240’
Request

Parameters:

{“id”=>“show”}

On 20 June 2012 08:51, Timen E. [email protected] wrote:

undefined method `user’ for #Array:0x3c81ac8
Extracted source (around line #3):

@card is a collection of cards (that’s how you populate it in the
“show” action. If it needs to be a single card, you need to find it by
ID (or some other attribute), if it’s supposed to be a collection of
every card, you need to iterate it in the view and print the user for
each card.

On 20 June 2012 08:51, Timen E. [email protected] wrote:

cardlevel.rb
has_many :cards
end

card_controller.rb
class CardController < ApplicationController
def show
@card = Card.all

You would have been better to put @cards = Card.all as the result will
be be an (effectively) an array of cards not a single one.

etc.

The error:
Showing c:/tuts/kaartje/app/views/card/show.html.erb where line #3
raised:

undefined method `user’ for #Array:0x3c81ac8

The clue is in the error message, as is often the case, it says that
@card is an Array and the Arrray class does not have a method user.
You can only call user on an individual card.

Colin

Still got one(Hopefuly last for now) question, guys.

I’ve got the above data now and i can access my cards through users that
are joined by the cardlevel. I’m trying to loop through all the cards a
user has as such:
<% @user.cards.each do |c| %>
<%= c.name %>

<% end %>

And this works great. However i’d like to get some extra info about this
card from my cardlevel array, but i can’t seem to access it like this. I
can however loop it in a seperate each, but i don’t want that obviously.

Any ideas?

Thanks

Michael P. wrote in post #1065301:

On 20 June 2012 08:51, Timen E. [email protected] wrote:

undefined method `user’ for #Array:0x3c81ac8
Extracted source (around line #3):

@card is a collection of cards (that’s how you populate it in the
“show” action. If it needs to be a single card, you need to find it by
ID (or some other attribute), if it’s supposed to be a collection of
every card, you need to iterate it in the view and print the user for
each card.

aaah i see, nonetheless i noticed that i turned it around. I need to get
the user with it’s cards, haha!

[FORGET THIS PART, I FORGOT THE :TROUGH]

What you mentioned did work but it doesn’t seem to ‘associate’ the right
way around because i’m getting the error SQLite3::SQLException: no such
column: cards.user_id: SELECT “cards”.* FROM “cards” WHERE
“cards”.“user_id” = 1"".
Shouldn’t he query through cardlevels instead of cards?

Colin L. wrote in post #1065311:

On 20 June 2012 09:32, Timen E. [email protected] wrote:

card from my cardlevel array, but i can’t seem to access it like this. I
can however loop it in a seperate each, but i don’t want that obviously.

You have not explained well what you are trying to do, but possibly
you want to loop through the cardlevels instead of the cards, then for
each cardlevel you can obtain the card aswell as the other data, so
something like

<% @user.cardlevels.each do |cl| %>
<%= cl.card.name %>

<%= cl.other_data %>
<% end %>

You might need to check for cl.card nil though.

Colin

You’re my savior, thanks alot! It’s more the train of thought that needs
correcting than my code i guess.

On 20 June 2012 09:32, Timen E. [email protected] wrote:

card from my cardlevel array, but i can’t seem to access it like this. I
can however loop it in a seperate each, but i don’t want that obviously.

You have not explained well what you are trying to do, but possibly
you want to loop through the cardlevels instead of the cards, then for
each cardlevel you can obtain the card aswell as the other data, so
something like

<% @user.cardlevels.each do |cl| %>
<%= cl.card.name %>

<%= cl.other_data %>
<% end %>

You might need to check for cl.card nil though.

Colin