RailsNewb RailsNewb - 5 months ago 49
JSON Question

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

Answer

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/"