Nate Beers
Nate Beers

Reputation: 1425

Rails 4 - How to display a form for one model on another model's view

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

Answers (1)

svelandiag
svelandiag

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

Related Questions