AFG
AFG

Reputation: 1715

how can I pass a value between controllers (new -> create) in RoR

This may seem basic but I can't figure it out.

I have a "Write Review" link which looks as follows:

<%= link_to 'Write', new_review_path(@new, :vendor_id => @vendor.id) %>

This creates the URL:

reviews/new?vendor_id=10

All I want is to create a new Review object based on three inputs:

  1. vendor_id (above)
  2. user_id (which is working currently)
  3. @review hash from the form (which is working)

But I cannot get it to store the vendor_id:

  def new
    @review = Review.new
    @vendor = Vendor.find(params[:vendor_id])
    @vendor.reviews.create

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @review }
    end
  end

 def create
    @review = Review.new(params[:review])
    #@vendor = Vendor.find(params[:vendor_id]) #error

    #@review = @vendor.reviews.build #error

    @review = @current_user.reviews.build #build a review with the current_user id

    respond_to do |format|
      if @review.save
        flash[:notice] = 'Review was successfully created.'
        format.html { redirect_to(@review) }
        format.xml  { render :xml => @review, :status => :created, :location => @review }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @review.errors, :status => :unprocessable_entity }
      end
    end
  end

I am thinking I need to change the url in the form_for, but I'm not clear how. Here is what I have currently:

<% form_for(@review) do |f| %>
 ......

Can I have some help, please? Thanks!

Here is the view code for new (note: I also created a has_many route so that vendors/1/reviews/new has meaning, although I am not invoking it anymore):

My code in routes.rb:

map.resources :vendors, :has_many => :reviews

My code for views/reviews/new.html.erb:

<h1>New review for <%= @vendor.name%></h1>

Current User ID: <%= @current_user.id %>
Vendor ID: <%= @vendor.id %> <%= @review.vendor.id %>
Current Review ID: <%= @review.id %>

<% form_for @review do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :summary %><br />
    <%= f.text_field :summary %><br />

    <%= f.label :pro_review %><br />
    <%= f.text_field :pro_review %><br />

    <%= f.label :con_review %><br />
    <%= f.text_field :con_review %><br />

    <%= f.label :detail_review %><br />
    <%= f.text_field :detail_review %>  <br />

  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

<%= link_to 'Back', reviews_path %>

Here is the source view:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Reviews: new</title>
  <link href="/stylesheets/scaffold.css?1238999620" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>

<p style="color: green"></p>

<h1>New review for Fiberlink</h1>

Current User ID: 2
Vendor ID: 16 16
Current Review ID: 

<form action="/reviews" class="new_review" id="new_review" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="XDknE1mvQT4zwem1z/gCYm8I2ODhqHLKKgd8y12zzzo=" /></div>


  <p>
    <label for="review_summary">Summary</label><br />
    <input id="review_summary" name="review[summary]" size="30" type="text" /><br />

    <label for="review_pro_review">Pro review</label><br />
    <input id="review_pro_review" name="review[pro_review]" size="30" type="text" /><br />

    <label for="review_con_review">Con review</label><br />
    <input id="review_con_review" name="review[con_review]" size="30" type="text" /><br />

    <label for="review_detail_review">Detail review</label><br />
    <input id="review_detail_review" name="review[detail_review]" size="30" type="text" />  <br />

  </p>
  <p>
    <input id="review_submit" name="commit" type="submit" value="Create" />
  </p>
</form>

<a href="/reviews">Back</a>

</body>
</html>

Upvotes: 0

Views: 1005

Answers (2)

Matt Darby
Matt Darby

Reputation: 6324

I would normally do:

<% form_for Review.new, :url => new_review_path do |f| %>
  <%= f.hidden_field :vendor_id, :value => @vendor.id %>

Upvotes: 1

Sarah Mei
Sarah Mei

Reputation: 18484

You're almost there. You need a slight change to your new method.

  def new
    @review = Review.new
    @vendor = Vendor.find(params[:vendor_id])
    @review.vendor = @vendor # this will insert the vendor_id into the form
                             # when you do form_for

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @review }
    end
  end

EDIT: Try also adding a hidden field to your view code to hold the vendor_id.

<% form_for @review do |f| %>
  <%= f.hidden_field vendor_id %>
  # ...

EDIT 2: Actually, looking at the HTML the code generates, I think you need a slightly differnt form_for. The UI side of Rails is not my forte, as you can tell. :)

<% form_for :review, @review, :url => { :action => "create" } do |f| %>
  <%= f.hidden_field vendor_id %>
  # ...

Upvotes: 2

Related Questions