0

I am trying to retrieve data from a PostgreSQL database with Sequel in Sinatra.

DB = Sequel.connect('postgres://connection_data')
items = DB[:items]

Then I try to get an entry with a specific ID:

get '/:id' do
   @item = items.filter(:id => params[:id]) 
   erb :edit
end

In my edit view I would like to display the content of the @item variable. The problem is that I don´t know how to get for example the ID.

<% if @item %>
   <a href="/<%= @item.id %>/doit">Do something</a>
<% else %>
   <p>Item not found.</p>
<% end %>

I tried using @item.id and @item[:id] but both don´t work. I get an error undefined method 'id' for #<Sequel::Postgres::Dataset:0x007fac118b7120>. What would be the right way to retrieve the values from the @item variable?

Chris
  • 6,093
  • 11
  • 42
  • 55

2 Answers2

0

Actually @item.id is the right way. The only problem I can see in your code is

@item = items.filter(:id == params[:id]) 

which should be

@item = items.filter(:id => params[:id].to_i) 

EDIT:

Try this:

@item = items.where(:id => params[:id].to_i)

@item.select(:id) #to embed

params[:id] is giving a string, so convert it to an integer.

Aakash Jain
  • 1,963
  • 17
  • 29
  • Thank you, I changed it but I still get an error "undefined method 'id' for # – Chris Mar 20 '14 at 15:47
  • Could you post your table description? It may seem like a silly questions but are you sure that the 'items' table has an 'id' attribute? – Aakash Jain Mar 20 '14 at 15:53
  • Yes I am sure, my table consist of three columns, "id", "name" and "price" and it has three rows. Counting my data or calculating the average just works fine, so the data is actually there. – Chris Mar 20 '14 at 15:55
  • 1
    Same error, I forgot to mention that I am using Heroku to deploy my files. When I tried to find out what type params[:id] is by using .type I got this weird error message: `NoMethodError - undefined method 'type' "favicon.ico":String` it seems as if `id` is a string containing "favicon.ico". How is that possible when all I do is open the URL myproject.herokuapp.com/1 – Chris Mar 20 '14 at 16:11
  • I haven't really worked with Heroku so far, so I can't comment, but that really is odd. Is it possible for you to try running the app locally? – Aakash Jain Mar 20 '14 at 16:17
  • The error seemed to be due to the id not being an integer but a string. However after converting it to int by using `to_i` I get the error `ERROR: argument of AND must be type boolean, not type integer LINE 1: SELECT * FROM "items" WHERE (("id" = 1) AND (id)) LIMIT 1`. Where does the `AND (id)` part come from? I am confused. – Chris Mar 20 '14 at 16:31
  • 1
    That should definitely not happen as the .to_i method returns a single value only. I would suggest asking on Sequel's mailing list. https://groups.google.com/forum/#!forum/sequel-talk – Aakash Jain Mar 20 '14 at 16:43
0

@item = items.filter(:id => params[:id]) returns a dataset. If you want a single item, you should do: @item = items.first(:id => params[:id].to_i)

Also @item.id is probably not want you want. Given that items = DB[:items], you are using a plain dataset and then @item = items.first(:id => params[:id].to_i) is going to give you a hash. You need to do @item[:id] to get the item's id.

You may want to look at using models instead:

# model file
class Item < Sequel::Model; end

# sinatra code
@item = Item[params[:id].to_i]

# template
@item.id
Jeremy Evans
  • 11,959
  • 27
  • 26
  • Thank you, in your example where would I put the part where I create the dataset? – Chris Mar 20 '14 at 16:47
  • Do you know where I could find an example of how to manage a project? Because somehow I have the feeling everyone does in a different way. Some don´t use models at all for example... – Chris Mar 20 '14 at 17:05