Search code examples
ruby-on-railsjsonformsapiactive-model-serializers

Getting NoMethodError (undefined method `id' for nil:NilClass) on Rails Json API when trying to create new article from rails frontend site


I am getting a NoMethodError (undefined method `id' for nil:NilClass) when I'm trying to create an article from my rails frontend site. I have a rails backend site which is where I have my rails API using model serializers and then I also have a rails frontend site which connects to the rails API using activeresource.

Frontend site form:

  <form action="/users/articles" method="post">
  <input name="authenticity_token" value="<%= form_authenticity_token %>" type="hidden">
  <div class="form-group">
    <%= label_tag 'article[title]', "name" %>
    <input type="text" name="article[title]" required>
  </div>
  <div class="form-group">
    <%= label_tag "article[content]", "E-Mail" %>
    <input type="text" name= "article[content]" required>
  </div>
  <div class="form-group">
    <%= label_tag "article[tags]", "Telephone" %>
    <input type="text" name= "article[tags]" required>
  </div>

  <input type="submit">
    <% if @errors %>
    <ul class="list-unstyled">
      <%@errors.each do |error|%>
        <li class="has-error"><%=error%></li>
      <% end -%>
    </ul>
  <% end %>
</form>

Frontend /users/ articles controller:

require 'rubygems'
require 'httparty'
module Users

class ArticlesController < UsersController
  # GET /articles/new
  # GET /articles/new.json
  def new
    @article = Article.new
  end

  # GET /articles/1/edit
  def edit
    @article = Article.find(params[:id])
  end

  # POST /articles
  # POST /articles.json
  def create
 @response =   HTTParty.post("http://localhost:3000/users/articles/",
  :body => { :title => params[:article][:title],
             :content => params[:article][:content],
             :tags =>  params[:article][:tags]
           }.to_json,
  :headers => { 'Content-Type' => 'application/json' } )
end

  # PUT /articles/1
  # PUT /articles/1.json
  def update
    @article = Article.find(params[:id])
    @article.user_id = current_user.id

    respond_to do |format|
      if @article.update(article_params)
        format.html { redirect_to @article, notice: 'Article was successfully updated.' }
        format.json { render :show, status: :ok, location: @article }
      else
        format.html { render :edit }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end
end
end

Error in Terminal From Backend site:

Started POST "/users/articles/" for ::1 at 2016-06-21 13:26:16 +0200
Processing by Users::ArticlesController#create as HTML
  Parameters: {"title"=>"frgr", "content"=>"grgrg", "tags"=>"rgr", "article"=>{"title"=>"frgr", "tags"=>"rgr", "content"=>"grgrg"}}
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)

NoMethodError (undefined method `id' for nil:NilClass):
  app/controllers/users/articles_controller.rb:52:in `create'

Article Model:

require 'active_resource'

class Article  < ActiveResource::Base
  self.site = "http://localhost:3000"
end

Routes File:

Rails.application.routes.draw do

  resources :users#, only: [:show]

  resources :articles

  namespace :users do
    resources :articles
  end

  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".

  # You can have the root of your site routed with "root"
   root 'welcome#index'

  # Example of regular route:
  #   get 'products/:id' => 'catalog#view'

  # Example of named route that can be invoked with purchase_url(id: product.id)
  #   get 'products/:id/purchase' => 'catalog#purchase', as: :purchase

  # Example resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Example resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Example resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Example resource route with more complex sub-resources:
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', on: :collection
  #     end
  #   end

  # Example resource route with concerns:
  #   concern :toggleable do
  #     post 'toggle'
  #   end
  #   resources :posts, concerns: :toggleable
  #   resources :photos, concerns: :toggleable

  # Example resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
end

Solution

  • The path in your create action:

    @response =   HTTParty.post("http://localhost:3000/users/articles/"
    

    It does not include user id in it, hence its throwing nil for id error. The path should be:

    @response =   HTTParty.post("http://localhost:3000/users/user_id/articles/"
    

    where user_id is the id of the user i.e.,it will look as below:

    @response =   HTTParty.post("http://localhost:3000/users/5/articles/"