ruby-on-railscontrollerassociationsbelongs-tobutton-to

Input new record into database using a form with the association belongs_to


I’m relatively new to ruby on rails so bear with me. I'm trying to create an app where there are many Projects with specific Issues associated to each project. The following is my code:

My Models:

class Issue < ActiveRecord::Base
belongs_to :project
end

class Project < ActiveRecord::Base
has_many :issues
has_and_belongs_to_many :users
validates :name, :description, :manager, presence: true
validates :name, uniqueness: true
end

My Controllers:

in project_controller.rb

def create
@project = Project.new(project_params)

respond_to do |format|
  if @project.save
    format.html { redirect_to @project, notice: "Project #{@project.name} was successfully created." }
    format.json { render :show, status: :created, location: @project }
  else
    format.html { render :new }
    format.json { render json: @project.errors, status: :unprocessable_entity }
  end
end
end

in issues_controller.rb

def create        
@issue = Issue.new(params[:issue])
project = Project.find(params[:project_id])


respond_to do |format|
  if @issue.save
    format.html { redirect_to root_path, notice: "A new Issue was successfully added to project #{project.name}." }
    format.json { render :show, status: :created, location: @issue }
  else
    format.html { render :new }
    format.json { render json: @issue.errors, status: :unprocessable_entity }
  end
end
end

My project index html file which is also my root url:

<tbody>
<% @projects.each do |project| %>
  <tr>
    <td><%= project.name %></td>
    <td><%= project.manager %></td>
    <td><%= project.description %></td>
    <td><%= project.created_at.strftime("%d %B %Y @ %H:%M") %></td>
    <td><%= button_to 'Report An Issue', new_issue_path(project_id: project) %>
    <td><%= link_to 'Show', project %></td>
    <td><%= link_to 'Edit', edit_project_path(project) %></td>
    <td><%= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>

My question is how am i supposed to define the create method in issues_controller.rb to open the new.html.erb form get input from user then save in database while being linked to the project the report an issue button referred to. Any answers, insights or additional links i can look at would be greatly appreciated.

_form.html.erb

    <%= form_for(@issue) do |f| %>
  <% if @issue.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@issue.errors.count, "error") %> 
      prohibited this  issue from being saved:</h2>

      <ul>
      <% @issue.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <fieldset>
  <legend><strong>Enter Issue Details</strong></legend>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>
  <div class="field">
    <%= f.label :type %><br>
    <%= f.text_field :type %>
  </div>
  <div class="field">
    <%= f.label :status %><br>
    <%= f.text_field :status %>
  </div>
  <div class="field">
    <%= f.label :reporter %><br>
    <%= f.text_field :reporter %>
  </div>
  <div class="field">
    <%= f.label :remarks %><br>
    <%= f.text_area :remarks %>
  </div>
  <div class="field">
    <%= f.label :priority %><br>
    <%= f.text_field :priority %>
  </div>
  <div class="field">
    <%= f.label :assignedto %><br>
    <%= f.text_field :assignedto %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
  </fieldset>
  <% end %>

new.html.erb

<h1>New Issue</h1>

   <%= render 'form' %>

   <%= link_to 'Back', issues_path %>

I have to reinput the url /issues/new?project_id=15 manually for it to open the form page otherwise i get routing error and after submission it gives me Couldn't find Project with 'id'=


Solution

  • You are on the right track, you have created an association, now you just need to reference the project in the create method like this :

    def new 
      @project = Project.find params[:project_id]
      @issue = @project.issues.build 
    end
    
    
    def create  
      @project = Project.find(params[:project_id])      
      @issue = @project.issues.build(issue_params)
      ## rest of code
    end
    

    then in your _form.html.erb you should now have :

    form_for [@project,@issue] 
       #rest of code