LearningRoR
LearningRoR

Reputation: 27192

Action method is :id with link_to?

When I try to subscribe to a product by clicking the link:

<%= link_to "Subscribe", :controller => "products", :action => "subscribe_product", :id => product.id, :method => :post %>

I get this error and notice the parameters are wrong.

ActiveRecord::RecordNotFound in ProductsController#show

Couldn't find Product with id=subscribe_product

{"id"=>"subscribe_product", "method"=>"post"}

My subscribe_product method in my ProductsController is:

def subscribe_product
  @product = Product.find(params[:id])
  @product.subscriptions.create(:subscriber_id => current_user.id)
end

My route:

resources :products do
  post :subscribe_product, :on => :collection
end

These are the associations:

class User
  has_many :products
  has_many :subscriptions, :foreign_key => :subscriber_id

class Product
  belongs_to :user
  has_many :subscriptions, :as => :subscribable

class Subscriptions
  belongs_to :subscriber, :class_name => "User"
  belongs_to :subscribable, :polymorphic => true

Users subscribe in another controller:

PagesController
  def index
   @product_history = current_user.products
  end
end

pages/index.html.erb

<% for product in @product_history %>
  <%= product.name %>
  <%= product.price %>
  <%= link_to "Subscribe", :controller => "products", :action => "subscribe_product", :id => product.id, :method => :post %>
<% end %>

So why is my action method being seen as the ID instead?

Upvotes: 0

Views: 835

Answers (3)

tsherif
tsherif

Reputation: 11710

Since you're passing an id, the subscribe_product route should be a member route. Try this, and let me know what you get:

resources :products do
  member do
    post 'subscribe_product'
  end
end

In the controller (to get around non-mass-assignable attributes):

def subscribe_product
  @product = Product.find(params[:id])
  subscription = Subscription.new
  subscription.subscriber_id = current_user.id
  @product.subscriptions << subscription
end

Upvotes: 1

user435773
user435773

Reputation:

Try :

resources :products do
  post :subscribe_product, :on => :member
end

It will generate routes like :

subscribe_product_product POST     /product/:id/subscribe_product(.:format)   {:action=>"subscribe_product", :controller=>"products"}

and use path like in view :

subscribe_products_path(product.id)

Upvotes: 2

Spyros
Spyros

Reputation: 48626

Please try this. Change your route to :

resources :products do
  post :subscribe
end

Then change your link like :

<%= link_to "Subscribe", subscribe_products_path(:id => product.id), :method => :post %>

Upvotes: 1

Related Questions