darkginger
darkginger

Reputation: 690

Lookup value from table based on attribute from separate table in Rails 4

I am trying to use data from two models in the same table of a view in without a Join table.

I want to show a Game_id and Score from the Points table. In a third column, I want to use the game_id from Points to lookup the value in the Name column of the Game model matching that same id from Points.

In the ScoreboardController that will apply to this table, I am trying to first select a set of Points and then query the ID:

    @points = Point.where(user_id: current_user.id).order(game_id: :desc)
    @find = @points.pluck(:game_id).last
    @game = Game.where(id: @find)

Ok, so I am going to show the full list of @points, which includes an id integer for game_id. I then try to look up matching game with @game.

Next, I want to show this in a table with the third column picking the .name from the row in @game.

<tbody>
        <% @points.each do |point| %>
        <tr>
            <td><%= point.game_id %></td>
            <td><%= point.virtualmoney %></td>
            <% @game.each do |game| %>
                <td><%= game.name %>
            <% end %>
         <% end %>
        </tr>
    </tbody>

This correctly shows rows of all game_ids in the Points model with virtualmoney earned for that game. I then try to do a second iteration loop with game.name -- it loads, but it basically returns the first value for every single row.

So instead of "id: 1 | currency: 5| name: "game 1" ... id: 2 | currency: 3| name: "game 2", it would just be "game 1", "game 1", and so on).

What should I do to return to return a name for each row matching the game_id in the first column?

EDIT: SCHEMA.RB SNIPPET

  create_table "games", force: true do |t|
    t.string   "name"
    t.integer  "max_players"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

 create_table "points", force: true do |t|
    t.integer "game_id"
    t.integer "user_id"
    t.integer "points",   default: 0
  end

Upvotes: 0

Views: 245

Answers (2)

Sharvy Ahmed
Sharvy Ahmed

Reputation: 7405

If you have correct associations, the following will serve your need:

<tbody>
    <% @points.each do |point| %>
      <tr>
        <td><%= point.game_id %></td>
        <td><%= point.virtualmoney %></td>
        <td><%= point.game.name %></td> 
      </tr>
    <% end %>
</tbody>

The thing is, Game has_many points, and Point belongs_to a Game. So you can get associated game name from your a point object by this - point.game.name. Though this violates the law of demeter, but it will do what you need.

Upvotes: 1

Ben Hawker
Ben Hawker

Reputation: 949

I am not fully understanding what you are trying to do, but hopefully the following points can help. If I understand correctly the following lines are doing nothing:

<% @game.each do |game| %>
  <td><%= game.name %>
<% end %>

because...

@find = @points.pluck(:game_id).last
##Will return only one Game id (e.g. 1)

@game = Game.where(id: @find)
## Will return a ActiveRecord Collection with only one game.

In this instance you may well be better off using:

@game = Game.find(@find)

This is equivalent to calling:

@game = Game.where(id: @find).first

So when iterating through @game you just iterating through an ActiveRecord Collection that contains only 1 item.

Including the basic associations you have added would help to understand better.

Upvotes: 0

Related Questions