If you keep up with my #100DaysofCode, you will know that I am working on another rails application to show on my portfolio. Today I focused on the application and made a few updates.
I am still using the unsplash gem to display images on my application. The goal is to allow a user to search for a picture and then if they like it, they can use a check box and add it to their profile. Seems simple, but I keep running into an issue.
First, I iterate over the Unsplash gem and create a new Photo instance.
photos = Unsplash::Photo.search("cats")
@photos = []
photos.each do |p|
a = Photo.new(photo: p["urls"].full, quote: p["alt_description"] )
@photos << a
end
Then, I display it on the index show page so that a user can view the photos:
<%= form_tag(new_photo_path, {:method => :get}) do %>
<% @photos.each do |p| %>
<img src="<%= p.photo %>" alt="random" ><br>
<div><p> <%= p.quote %> </p></div><br>
<%= check_box_tag "photo_ids[]", p , true%>
<% end %>
<%= submit_tag "Submit Post" %>
<% end %>
Above p
is equal to #<Photo id: nil, photo: "https://images.unsplash.com/photo-894384059358603-a3...", quote: "selective focus photography brown cat lying over b...", created_at: nil, updated_at: nil>
The issue occurs when I get to the controller. I put a byebug
in my new
method and when I check the params I get the following:
(byebug) params
<ActionController::Parameters {"photo_ids"=>["#<Photo:0x00007f9620c97d28>", "#<Photo:0x00007f961bb58278>", "#<Photo:0x00007f9620880528>", "#<Photo:0x00007f9620a54160>", "#<Photo:0x00007f961cd44cc0>", "#<Photo:0x00007f9620d86fb8>", "#<Photo:0x00007f961ba078d8>", "#<Photo:0x00007f961cbd5b50>", "#<Photo:0x00007f961cc34f88>", "#<Photo:0x00007f9620c25a48>"], "commit"=>"Submit Post", "controller"=>"photos", "action"=>"new"} permitted: false>
It appears that the photos are the Photo objects that have not been saved yet, which I thought was great, Ill just save them in the method right? WRONG! I have no idea how to save it from here. I have tried saving it into a variable and then saving. I have tried referencing the items within the object.
(byebug) a = params[:photo_ids][1]
"#<Photo:0x00007f961bb58278>"
(byebug) a.save
*** NoMethodError Exception: undefined method `save' for "#<Photo:0x00007f961bb58278>":String
nil
(byebug)
No luck. It looks like the checkbox is sending it as a string as opposed to the object itself. I know I can not find the object based off the id
since the id
does not exist yet. Is there a way around this or just a better way to do this process in general?
I am trying to avoid creating/saving the unsplash items immediately to my database, I do not want to save until after a user has selected it. I will try again tomorrow, hopefully find a way to get this task done.
Fun Fact : For the past few days my rails console was not working. I thought it was my computer but then I googled: "rails console not working"
Saw the following Stack Overflow Question
Ran spring stop
and then rails console
and my console was working again. I have no idea what spring stop
does but I wanted to share for any other code newbies who may run into this issue.
As always, thanks for reading!
Sincerely,
Brittany
Song of the Day:
Top comments (4)
Hi Brittany.
I am not sure i would recommend creating the instance first before rendering it in the view and the
photo_ids
param doesn't really mean much since they don't have ids yet. Maybe we could have a video chat to work through it because i can't really figure how out how to fix it.Hi Mbonu,
I would love to schedule a time to video chat and go over it. I know that the name
photo_ids
does not really make sense since they do not have ids yet, I will rename the param tophoto_objects
but I do not know if/how I can go about referencing that instance. I will private message you to set up a time. Thank you again!I just sent you a DM on twitter
There are many things going on here, but here are a few pointers.
First,
<%= check_box_tag "photo_ids[]", p , true%>
should be
<%= check_box_tag "photo_ids[]", p.id , true%>
The id that will be returned here being the Unsplash photo id.
Second, since you used p, what you receive in the params[:photo_ids] is an array of strings. Even though it looks like the fingerprint of the object, it's not the object anymore but its fingerprint.
So when you call
params[:photo_ids][1].save
, you're calling save on a string (the string representation of the object, "#Photo:0x00007f961bb58278").Hence the error
NoMethodError Exception: undefined method
save' for "#Photo:0x00007f961bb58278":Stringwhich tells you that there is no
save` method for String objects.