l1zZY
l1zZY

Reputation: 100

The "show" page isn't displaying the property of the correct data

I'm making a website using ror and I have a list of fandoms, and I want to display different pictures and writing for that fandom. Right now, just for testing, I'm having it just display the name of the fandom at the top of the page, but no matter which one I click on, it only displays the name of the first fandom. Here's the parts of the files I think are relevant, but if you need to see more, I'll post it.

Section of routes.rb:

get 'fandoms' => 'fandoms#index'
get 'fandoms/new' => 'fandoms#new'
post 'fandoms' => 'fandoms#create'
get 'fandoms/:id' => 'fandoms#show', as: :fandom
resources :fandoms

The show method in fandoms_controller:

def show
    @fandom = Fandom.find_by(params[:id])
end

The index.html.erb for fandoms:

<div class="main">
<div class="container">
<h2>Fandoms</h2>
  <%= link_to "New Fandom (dev only)", "fandoms/new" %>
  <% @fandoms.each do |fandom| %>
  <div class="fandoms">
    <%= link_to fandom.name, fandom_path(fandom) %>
  </div>
  <% end %>
</div>

And finally the show.html.erb for fandoms:

<div class="main">
  <div class="container">
  <h2>Fandoms</h2>
      <div class="fandom">
        <h1><%= @fandom.name %></h1>
      </div>
  </div>
</div>

I double checked my code with the Ror tutorial on codecademy, but I still couldn't find any differences for what I wanted to do.

Thanks.

Upvotes: 0

Views: 29

Answers (1)

Robert Nubel
Robert Nubel

Reputation: 7522

Your show action has a subtle typo that's breaking your logic:

@fandom = Fandom.find_by(params[:id])

Should actually be:

@fandom = Fandom.find(params[:id])

The difference is, find_by will return the first row for which the conditions passed are met. You're not actually passing any conditions; just an ID, which in Postgres doesn't even work:

irb> Fandom.find_by(1)
PG::DatatypeMismatch: ERROR:  argument of WHERE must be type boolean, not type integer
LINE 1: SELECT  "fandoms".* FROM "fandoms" WHERE (1) LIMIT 1

Your database is more permissive, but seems to be treating it just as a WHERE TRUE clause and thus every single row meets the condition. As such, it returns the first row every time. Using find(id) will give you the desired result.

Upvotes: 2

Related Questions