Liz
Liz

Reputation: 1437

Rails has_many/belongs_to Not Working

I have an app in which I have user, request, and proposal models. They're structured like this. A user has many proposals and requests:

class User < ActiveRecord::Base
  has_many :requests
  has_many :proposals
end

A request belongs to a user and has many proposals:

class Request < ActiveRecord::Base
    belongs_to :user
    has_many :proposals
end

A proposal belongs to a user and a request. Whatever user the request belongs to should also have the proposal:

class Proposal < ActiveRecord::Base
  belongs_to :user
  belongs_to :request
end

I have it set up like this in my schema.rb:

create_table "proposals", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "request_id"
    ...
    t.string   "status",               default: "Proposal Created"
    t.datetime "created_at",                                        null: false
    t.datetime "updated_at",                                        null: false
  end

  add_index "proposals", ["request_id"], name: "index_proposals_on_request_id"
  add_index "proposals", ["user_id"], name: "index_proposals_on_user_id"

  create_table "requests", force: :cascade do |t|
    t.string   "project_title"
    ...
    t.integer  "user_id"
  end

  add_index "requests", ["user_id"], name: "index_requests_on_user_id"

I have a proposal#new/proposal#edit view form in which I set the :request using a hidden_field:

<%= f.hidden_field :request, value: @request %>

Then, when I try to call the project_title of the request that has a proposal on the proposal#show page (<%= @proposal.request.project_title %>) it comes out as nil.

Can anyone help me restructure things to get this working right? The only complicated thing I'm trying to do is, following this blog I'm trying to get the value of the request by which link is clicked. Here's my proposals_controller:

class ProposalsController < ApplicationController
  before_action :set_proposal, only: [:show, :edit, :update, :destroy]

  # GET /proposals
  def index
    @proposals = Proposal.all
  end

  # GET /proposals/1
  def show
  end

  # GET /proposals/new
  def new
    @request = Request.find(params[:request_id])
    @proposal = Proposal.new
  end

  # GET /proposals/1/edit
  def edit
    @request = Request.find(params[:request_id])
    @proposal = Proposal.find(params[:id])
  end

  # POST /proposals
  def create
    @request = Request.find(params[:request_id])
    @proposal = @request.proposals.new
    @proposal.user = @request.user

    if @proposal.save
      redirect_to request_proposal_path(@request, @proposal), notice: 'Proposal was successfully created.'
    else
      render :new
    end
  end

  # PATCH/PUT /proposals/1
  def update
    if @proposal.update(proposal_params)
      redirect_to @proposal, notice: 'Proposal was successfully updated.'
    else
      render :edit
    end
  end

  # DELETE /proposals/1
  def destroy
    @proposal.destroy
    redirect_to proposals_url, notice: 'Proposal was successfully destroyed.'
  end

  def unarchive
    @proposal = Proposal.find(params[:id])
    if @proposal.update_attributes(status: "Sent to Client")
      FavoriteMailer.send_proposal_to_client(@proposal, @proposal.user).deliver_now
      flash[:notice] = "That proposal has sent to the client."
      redirect_to :back
    else
      flash[:alert] = "That proposal could not be sent right now."
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_proposal
      @proposal = Proposal.find(params[:id])
    end

    # Only allow a trusted parameter "white list" through.
    def proposal_params
      params.require(:proposal).permit(:user_id, :request_id, :executive_summary, :situation_analysis, :strategy_online, :strategy_real_world, :strategy_credentials, :strategy_timeline, :respond_by, :timetable, :financials, :conditions, :acceptance, :status)
    end
end

And here are my routes:

get 'proposal/:request', to: 'proposals#new', as: 'new_proposal'
resources :proposals

Anyone see where I'm going wrong?

Upvotes: 0

Views: 99

Answers (1)

MZaragoza
MZaragoza

Reputation: 10111

have you try doing something like this in your routes

   resources:requests do
     resources :proposals
   end

response

                  request_proposals GET        /requests/:request_id/proposals(.:format)                                        proposals#index
                                    POST       /requests/:request_id/proposals(.:format)                                        proposals#create
               new_request_proposal GET        /requests/:request_id/proposals/new(.:format)                                    proposals#new
              edit_request_proposal GET        /requests/:request_id/proposals/:id/edit(.:format)                               proposals#edit
                   request_proposal GET        /requests/:request_id/proposals/:id(.:format)                                    proposals#show
                                    PATCH      /requests/:request_id/proposals/:id(.:format)                                    proposals#update
                                    PUT        /requests/:request_id/proposals/:id(.:format)                                    proposals#update
                                    DELETE     /requests/:request_id/proposals/:id(.:format)                                    proposals#destroy
                           requests GET        /requests(.:format)                                                              requests#index
                                    POST       /requests(.:format)                                                              requests#create
                        new_request GET        /requests/new(.:format)                                                          requests#new
                       edit_request GET        /requests/:id/edit(.:format)                                                     requests#edit
                            request GET        /requests/:id(.:format)                                                          requests#show
                                    PATCH      /requests/:id(.:format)                                                          requests#update
                                    PUT        /requests/:id(.:format)                                                          requests#update
                                    DELETE     /requests/:id(.:format)                                                          requests#destroy

to make a new proposals you would do: new_request_proposal_path(@request)

Upvotes: 1

Related Questions