While building my latest rails app I wanted to pass the id of a video episode to my subscription service. I wanted to build a URL that looked something like this:

http://localhost:3000/subscriptions/new?episode=2

But I didn’t want to just hard code it. I wanted to do it the rails way (using the named paths). Here’s I did it:

new_subscription_path(:episode => {:episode_id => episode.id}) }

or by hand

href=”/subscriptions/new?episode[episode_id]=”

Which both produce this URL:

http://localhost:3000/subscriptions/new?episode[episode_id]=2

or base64 encoded

http://localhost:3000/subscriptions/new?episode%5Bepisode_id%5D=2

And this is how I can pull the episode id from the URL in my controller:

@episode = Episode.find(params[:subscription][:episode_id])

Here is a full code example with tests:

subscription_pages_spec

require 'spec_helper'

describe "Subscription" do

  subject { page }

  describe "new subscription page" do
    let!(:user) { FactoryGirl.create(:user) }
    let!(:episode) { FactoryGirl.create(:episode, title: "This episode" ) }

    describe "not signed in" do
      before { visit new_subscription_path(:episode => {:episode_id => episode.id}) }
      it { should have_title "Sign in" }
    end

    describe "should return to New Subscription after signing in" do
      before do
        visit new_subscription_path(:episode => {:episode_id => episode.id})
        sign_in user
      end
      it { should have_title "My Cart"}
      it { should have_content('Nice choice!') }
    end

    describe "signed in" do
      before { sign_in user }

      describe "should display new subscription page" do
        before { visit new_subscription_path(:episode => { :episode_id => episode.id}) }
        it { should have_title "My Cart"}
        it { should have_content('Nice choice!') }
      end
    end

    describe "signed in and subscribed" do
      before do
        user.subscribe!(episode)
        sign_in user
      end

      describe "should show video" do
        before { visit new_subscription_path(:episode => { :episode_id => episode.id}) }
        it { should have_title "This episode"}
        it { should have_content('Already subscribed') }
      end

    end

  end
end

View.erb

      <div class="text-centered">
        <a id="Watch now" class="btn btn-large btn-primary" href="/subscriptions/new?episode[episode_id]=<%= @episode.id %>">Watch Now
          <span class="subprice">Only $<%= @episode.price %></span>
        </a>
      </div>

Controller.rb

  def new

    @episode = Episode.find(params[:episode][:episode_id])

    if signed_in? && current_user.subscribed?(@episode)
      redirect_to @episode, notice: 'Already subscribed. Enjoy the video!'
    else
      flash[:notice] = "Nice choice! Project management is super important and this is a great video."
    end

  end

Links that help

http://stackoverflow.com/questions/10773695/rails-passing-parameters-in-link-to
http://stackoverflow.com/questions/1898737/pass-parameter-by-link-to-ruby-on-rails