views:

54

answers:

1

I have 3 models: Questions, Answers, and Profiles (I know, it should be called "Users"). When you view a question Q, I query the database for the answers to Q. (They are linked by id.) In the view, the current user has the option to delete his answer by clicking on the destroy link displayed next to his answer:

%table
  %tr
    %td
      Answers:
  - @answers.each do |a|
    %tr
      %td
        - @provider = Profile.find(a.provider)
        %i
          #{h @provider.username} said:
        %br
        #{h a.description}
      %td
        = link_to 'View full answer', a
      %td
        - if a.provider == @profile.id
          #{link_to 'Delete my answer', a, :confirm => 'Are you sure?', :method => :delete}

The problem is that when the user clicks on the destroy link, it redirects to the /answers/index. I want it to redirect to /questions/Q. What's the best way to do this?

I know that there's a redirect_to method, but I don't know how to implement it when I want to redirect to an action for a different controller. It also needs to remember the question from which the answer is being deleted.

I tried passing something like :question_id in link_to as:

#{link_to 'Delete my answer', a, :confirm => 'Are you sure?', :question_id => @question.id, :method => :delete}

In AnswersController#destroy:

  def destroy
    @answer = Answer.find(params[:id])
    @answer.destroy

    respond_to do |format|
      format.html { redirect_to(answers_url) }
      format.xml  { head :ok }
    end

    @question = Question.find(params[:question_id])
    redirect_to question_path(@question)
  end

The :question_id information is not passed to the destroy method, so I get this error:

Couldn't find Question without an ID

To confirm, I added a puts call before Question.find, and it returned nil.

I have also tried storing the question id in the session information. AnswersController#destroy changes to call session[:question_id] instead of params[:question_id]. But, I get a different error:

Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".

I'm not sure how to address is error. Where should I put the return?

Any help would be appreciated!!

+2  A: 

In the action that defines the destroy behaviour, you simply add a redirect_to on completion.

redirect_to can use any of you standard url/rout helper methods:

Assuming you have a Questions controller and associated routs and actions, you could use:

redirect_to question_path(@question)

In the edited case above, you need to ensure the question_id is passed correctly:

link_to 'Delete my answer', answer_path(a, :question_id => @question.id), :confirm => 'Are you sure?', :method => :delete

link_to's second param is the URL in question. You can check the generated HTML to confirm the data is being rendered as you expect.

There are also some other options here:

Depending on how your routes and relationships are set up, you may be able to make Answer a nested route that lives inside the Question context. Which would give you a set of question_answer_path helpers.

If the Answer belongs to the Question, you could actually just use answer.question_id in the destroy action and save the hassle :P

Toby Hede
Hmm, I have tried a version of that, but I still have the issue of "saving" and retreiving the question in the first place.I have amended my question to reflect this information.Thanks!
Teef L
Ah, thank you! I'm going to have to set up those relations.
Teef L