0

I have a subscriptions form where I am trying to set the plan the user has chosen, the business they would like to associate with the subscription and the payment details. In my form I use a select tag to display a list of all of the businesses and it displays properly in my view but upon save I get the following error:

undefined method `map' for #<Business:0x007f8ea7955b90>

new.html.erb

<div class="field">
  <%= select_tag :business_id, options_from_collection_for_select(@businesses, "id", "name") %>
</div>

subscriptions_controller.rb

...

def new
  @subscription = Subscription.new
  @plan = Plan.find(params["plan_id"])
  @businesses = Business.all
end

def create
  @subscription = Subscription.new(subscription_params)
  raise "Please, check subscription errors" unless @subscription.valid?
  @subscription.process_payment
  @subscription.save
  redirect_to @subscription, notice: 'Subscription was successfully created.'
rescue => e
  flash[:error] = e.message
  render :new
end

private

  def set_subscription
    @subscription = Subscription.find(params[:id])
  end

  def subscription_params
    params.require(:subscription).permit(:plan_id, :business_id, :card_token, :coupon)
  end

Am I setting up the select_tag properly? Do I need to fix my create method? Looked at other solutions on SO with little success.

enter image description here

Justin Seidl
  • 249
  • 1
  • 2
  • 13
  • Could you add some lines from the top of your error stack trace? Up to ten lines ought to be enough, I'd think. – amar47shah Aug 03 '15 at 20:15
  • @amar47shah does the above image help? – Justin Seidl Aug 03 '15 at 20:21
  • Yes, that does help. It looks like the `create` action attempted to render the `new` template again, probably because the new subscription was not valid. Note that `render :new` doesn't call the `new` action in the controller. It's still hard for me to tell what's going on, though. It looks like the value of `@businesses` has changed from a collection to a single business, but I can't tell why. Just for debugging purposes, try setting `@businesses = Business.all` again in the `create` action's `rescue` block. Oh wait, now I have an idea! – amar47shah Aug 03 '15 at 20:30
  • @amar47shah I'm pulling in the business collection so a user can select from one of all my businesses they would like to start their subscription with. – Justin Seidl Aug 03 '15 at 20:34
  • @amar47shah do you still have an idea on how to fix? – Justin Seidl Aug 03 '15 at 20:57
  • Writing it up :) Unfortunately, I can't test it so I am trying to add helpful details. Just one moment. – amar47shah Aug 03 '15 at 20:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/85038/discussion-between-amar47shah-and-justin-seidl). – amar47shah Aug 03 '15 at 21:08

1 Answers1

0

Rails instantiates a new controller for every request. There's some information about that here.

This means that any instance variables you've set in new won't be available when you process the POST in create.

In your case, you are rendering the :new template in the rescue block of the create action when the new subscription fails validation. You're only getting the error at this point, not when you originally access the form.

The problem is that render :new doesn't call the new action; it just renders the template. In the case where the subscription fails validation and the form is re-rendered, the new action has never been called by this controller instance, and the instance variables do not have the values expected by the template.

Try this instead of render :new:

redirect_to new_subscription_url

This will instantiate a new controller and call the new action, so that you will be starting over with a clean slate. The instance variables needed in the new template will be assigned the correct values before the template is rendered.

As an alternative, you could set the instance variables in the rescue block:

def create
...
rescue => e
  flash[:error] = e.message
  @businesses = Business.all
  render :new
end

Here's a similar question on Stack Overflow.

Hope that helps. Happy coding!

Community
  • 1
  • 1
amar47shah
  • 697
  • 4
  • 9