Reputation: 1425
I have an app where i have projects and each project has photos in it. Each photo has a status that I want to be able to update on the project's show page that lists all the photos in it. So each photo will have a drop down in the staus column displayed with the different statuses I have.
I am able to do this where I update the status on a separate page, no problem, but I need each photo to have the form displayed on the projects show page.
Here is my photos_controller.rb
class PhotosController < ApplicationController
def create
@project = Project.find(params[:project_id])
@photo = @project.photos.create(photo_params)
@photo.save
redirect_to @photo.project
end
def edit
@photo = Photo.find(params[:id])
@status_array = []
Status.all.each do |status|
@status_array << status.value
end
end
def update
@photo = Photo.find(params[:id])
@photo.update_attributes(photo_params)
redirect_to @photo.project
end
private
def photo_params
params.require(:photo).permit(:provider, :attachment, :image_id, :size, :data_url, :url, :project_id, :status)
end
end
Here is my projects_controller.rb
class ProjectsController < ApplicationController
before_action :authenticate_user!, only: [:show]
def create
@project = Project.create(project_params)
@project.creator = current_user.email
@project.save
redirect_to @project
end
def index
@projects = Project.all
end
def show
@project = Project.find(params[:id])
@photos = @project.photos
# @photo = Photo.find(params[:id])
end
private
def project_params
params.require(:project).permit(:project_num, :assigned, :project_status, :creator, :photo_id)
end
end
Here is my form views/photos/_edit.html.erb
<%= simple_form_for @photo do |f| %>
<div class="form-group">
<%= f.input :status, collection: @status_array %>
</div>
<div class="form-group">
<%= f.button :submit, "Submit", class: 'btn btn-success' %>
</div>
<% end %>
They way I was rendering the form in views/projects/show.html.erb
inside my show all photos loop is <%= render 'photos/edit' %>
<% if @project.photos %>
<% @project.photos.each do |photo| %>
<tr>
<td><%= image_tag("#{photo.data_url}") %></td>
<td><%= if photo.provider != "" then photo.provider.titleize else "Uncategorized" end %></td>
<td><%= photo.image_id %></td>
<td><%= photo.size %></td>
<td><a href="<%= photo.url %>">Link to image</a></td>
<td class="status-<%= photo.id %>">
<% if photo.status %>
<%= photo.status %>
<% else %>
Pending
<% end %>
<br>
<%= render 'photos/edit' %>
</td>
</tr>
<% end %>
<% else %>
<p>Sorry, this project has no photos currently</p>
<% end %>
The understand that I do not have @photo
declared in the projects controller show
action. (It is commented out currently). But when I do declare it, I don't have the params, I only have the params on the project id
so I can't find the photo that way and update it properly with the form. I am a bit lost here. Any thoughts are greatly appreciated.
Upvotes: 1
Views: 382
Reputation: 4320
You do not have defined the @photo
variable that's right, a good practice is to not use instance variables in partials, and always pass the variables manually to it, change your partial as follows:
<%= simple_form_for photo do |f| %>
<div class="form-group">
<%= f.input :status, collection: @status_array %>
</div>
<div class="form-group">
<%= f.button :submit, "Submit", class: 'btn btn-success' %>
</div>
<% end %>
and then when calling the partial send the current photo:
<% if @project.photos %>
<% @project.photos.each do |photo| %>
<tr>
<td><%= image_tag("#{photo.data_url}") %></td>
<td><%= if photo.provider != "" then photo.provider.titleize else "Uncategorized" end %></td>
<td><%= photo.image_id %></td>
<td><%= photo.size %></td>
<td><a href="<%= photo.url %>">Link to image</a></td>
<td class="status-<%= photo.id %>">
<% if photo.status %>
<%= photo.status %>
<% else %>
Pending
<% end %>
<br>
<%= render 'photos/edit', photo: photo %>
</td>
</tr>
<% end %>
<% else %>
<p>Sorry, this project has no photos currently</p>
<% end %>
Look at the render
we are passing the current photo, this way your update will work as expected. Make sure to do the same everywhere you render this partial.
Upvotes: 2