1
votes

I got this error

ActionController::UrlGenerationError in StaticPages#home
No route matches {:action=>"favorite", :controller=>"microposts", :id=>#<Micropost id: nil, content: nil, user_id: 101, created_at: nil, updated_at: nil, picture: nil, text: nil, type: nil, price: nil>, :type=>"favorite"} missing required keys: [:id]

Models:

class User< ApplicationRecord  
  has_many :microposts,dependent: :destroy
  has_many :favorite_microposts
  has_many :favorites, through: :favorite_micoposts, source: :micropost    
end

class Micropost < ApplicationRecord  
  has_many :favorite_microposts
  has_many :favorited_by, through: :favorite_microposts, source: :user
end         

class FavoriteMicropost < ApplicationRecord
  belongs_to :user
  belond_to :micropost
end

Micropost Controller:

class MicropostsController < ApplicationController
...
def favorite
 @micropost = Micropost.find(params[:id])  
 type = params[:type]
 if type == "favorite"
   current_user.favorites << @micropost
   redirect_to :back, notice: 'You favorited #{@micropost.number}'

 elsif type == "unfavorite"
   current_user.favorites.delete(@micropost)
   redirect_to :back, notice: 'Unfavorited #{@micrpost.number}'

 else
   # Type missing, nothing happens
   redirect_to :back, notice: 'Nothing happened.'
   end
  end
 end

Routes:

Rails.application.routes.draw do
resources :microposts do  
    match :favorite, on: :member, via: [:put, :delete]
  end
end

View:

<% if current_user %>
<%= link_to "favorite",   favorite_micropost_path(@micropost, type:"favorite"), method: :put%>
<%= link_to "unfavorite", favorite_micropost_path(@micropost, type: "unfavorite"), method: :put %>
<%end%>

rake routes

Prefix Verb       URI Pattern                        Controller#Action
    microposts POST       /microposts(.:format)              microposts#create
     micropost DELETE     /microposts/:id(.:format) microposts#destroy
favorite_micropost PUT|DELETE /microposts/:id/favorite(.:format) microposts#favorite
               GET        /microposts(.:format)              microposts#index
               POST       /microposts(.:format)              microposts#create
 new_micropost GET        /microposts/new(.:format)          microposts#new
 edit_micropost GET        /microposts/:id/edit(.:format)    microposts#edit

               GET        /microposts/:id(.:format)          microposts#show
               PATCH      /microposts/:id(.:format) microposts#update
               PUT        /microposts/:id(.:format) microposts#update
               DELETE     /microposts/:id(.:format)  microposts#destroy

this is my view of the micropost _micropost.html.erb:

 <div class="item  col-xs-4 col-lg-4">
        <div class="thumbnail" >
            <div class=img3>
            <%= image_tag micropost.picture.url ,class:"img3" %>
            </div>
            <div class="caption">
                <h4 >ay 7aga</h4>
                <p class="group inner list-group-item-text">
                   <%= micropost.content %></p>
                <div class="row">
                    <div class="col-xs-12 col-md-6">
                        <p class="lead">
                            <%= micropost.price %>
                            EGP</p>
                    </div>
                    <div class="col-xs-12 col-md-6">

                   <% if current_user %>
                    <%= link_to "favorite",   favorite_micropost_path(@micropost.id, type: "favorite"), method: :put %>
                    <%= link_to "unfavorite", favorite_micropost_path(@micropost.id, type: "unfavorite"), method: :put %>

                        <%end%>
                    </div>
                </div>
            </div>
        </div>
</div>

home.html.erb

  .....

 <% if logged_in? %>


  <div class="col-md-8">
<div class="container">
    <strong>feeds</strong>
  <%= render 'shared/feed' %>

Static Page controller

class StaticPagesController < ApplicationController
  def home
    if logged_in?
       @micropost  = current_user.microposts.build 
       @feed_items = Micropost.all.paginate(page: params[:page])
    end
  end
1
try this favorite_micropost_path(@micropost.id, type:"favorite")Vishal
Can you post the output of rails routes -c microposts ?Vishal
Prefix Verb URI Pattern Controller#Action favorite_micropost PUT|DELETE /microposts/:id/favorite(.:formAat) microposts#favorite GET /microposts(.:format) microposts#index POST /microposts(.:format) microposts#createKhaled Abd El-Moneim
Why have you tagged this as rails 3, rails 4 and rails 5? Which is it? (My guess is 5, since you're using ApplicationRecord.) Please delete the other tags.Tom Lord
@KhaledAbdEl-Moneim Post route details in questionVishal

1 Answers

0
votes

ActionController::UrlGenerationError in StaticPages#home No route matches {:action=>"favorite", :controller=>"microposts", :id=>#, :type=>"favorite"} missing required keys: [:id]

The problem is with @micropost = current_user.microposts.build which will be an unsaved record. That means the :id for @micropost will be nil, hence the error.

You need to fetch all microposts for a user and iterate through it like so

def home
  if logged_in?
    @microposts  = current_user.microposts
    @feed_items = Micropost.all.paginate(page: params[:page])
  end
end

<% if current_user %>
  <% @microposts.each do |micropost| %>
    <%= link_to "favorite",   favorite_micropost_path(micropost, type: "favorite"), method: :put %>
    <%= link_to "unfavorite", favorite_micropost_path(micropost, type: "unfavorite"), method: :put %>
  <% end %>
<% end %>