1

I'm making one simple rails application with simple forms for crud operations and one rails api that will have models and do all crud operations with data from rails application. In application i'm using ActiveResource. Currently i'm having some problems with update...Everything else works only when i update it breaks and i don't know why, plz help.

api/postcontroler

class API::PostsController < ApplicationController
  before_action :set_post, only: [:show, :update, :destroy]

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all

    render json: @posts
  end

  # GET /posts/1
  # GET /posts/1.json
  def show
    render json: @post
  end

  # POST /posts
  # POST /posts.json
  def create
    @post = Post.new(:title => params[:title], :content => params[:content])

    if @post.save
      render json: @post, status: :created, location: @post
    else
      render json: @post.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /posts/1
  # PATCH/PUT /posts/1.json
  def update

    if @post.update_attributes(post_params)
        render json: @post
    else
       render json: @post.errors, status: :unprocessable_entity
    end

  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post.destroy

    head :no_content
  end

  private

    def set_post
      @post = Post.find(params[:id])
    end

     def post_params
      params.require(:post).permit(:title, :id, :content)
    end

end 

application/postcontroler

class PostsController < ApplicationController

    before_action :set_post, only: [:show, :update, :edit, :destroy]

    def index
        @posts = Post.all
    end

    def new
        @post = Post.new(:title => "", :content => "")
    end

    def create
        @post = Post.new(post_params)
        if @post.save
            redirect_to post_path(@post)
        else
            render "new"
        end

    end

    def show

        @comments = Comment.find(:all, :params => {:post_id => params[:id]})
    end

    def edit
    end

    def update

        @post.title = params[:title]
        @post.content = params[:content]
        if @post.save
            redirect_to post_path(@post)
        else
            render "edit"
        end
    end

    def destroy
        @post.destroy
        redirect_to :action => 'index'
    end

    private

    def post_params
      params.require("post").permit(:title, :content)
    end

    def set_post
      @post = Post.find(params[:id])
    end
end

application/edit.html.erb

<%= form_for(@post, :url=>{:action=>'update'}) do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title %><br>
<%= f.label :content %><br>
<%= f.text_area :content %><br>
<%= f.submit %>
<% end %>

application routes

resources :posts do
        resources :comments
    end

api routes

namespace :api, :defaults => {:format => :json} do
    resources :posts, except: [:new, :edit] do
        resources :comments, except: [:new, :edit]
    end
  end

application active resource post model

class Post < ActiveResource::Base
    self.site = "http://localhost:3001/api"
end

I start application at port 3000 and api at 3001,when i try to update this happens

on application application

and this on api api

What's the problem?

  • Print params from within api/postscontroller, just before post.update_attributes(post_params). I think your redirect might not be passing the parameters on to this method. – Andrew Williamson Dec 29 '15 at 22:40
  • {"id"=>"7", "title"=>nil, "content"=>nil, "created_at"=>"2015-12-29T20:23:38.083Z", "updated_at"=>"2015-12-29T21:18:07.350Z", "format"=>"json", "controller"=>"api/posts", "action"=>"update"}....this comes back for puts params.inspect – Uros Certic Dec 29 '15 at 22:53
  • Your `params.require(:post).permit(:id, :title, :content)` is expecting id, title and content to be nested under an object called "post", like this: {"post"=>{"id"=>7, "title"=>"asdf", "content"=>"asdsdfsfs"}, "format"=>"json", etc... }. Notice in the response you posted, how title and content are nil. Something is wrong with how the parameters are being passed in. – Andrew Williamson Dec 29 '15 at 23:09
  • yea i understand that...but isn't application sending "post"=>{"title" =>"basd" , "content" => "lkasdj"}..as shown in http://i.stack.imgur.com/MG1P2.png – Uros Certic Dec 29 '15 at 23:16
  • Yeah the parameters look fine in that picture... It might have something to do with application/postcontroller#update calling `redirect_to post_path(@post)`. Those redirect methods normally take the id, not the whole object. – Andrew Williamson Dec 29 '15 at 23:27
  • Out of curiousity, why are you using two separate controllers? It seems like a large duplication of logic. You can just check, at the end of each action, if they requested json or html, and use one controller to do all the work. – Andrew Williamson Dec 29 '15 at 23:28
  • noup...just tried it with @post.id, same result – Uros Certic Dec 29 '15 at 23:30
  • Im learning how to use api-s...and the whole point of this is to have one front-end application and one api that will hold database. I know this example is not done in the best way but i just need to see basics – Uros Certic Dec 29 '15 at 23:36

1 Answers1

2

You have the formats mixed up for your two controllers.

api/postcontroller is expecting non-nested parameters, and application/postcontroller is expecting nested parameters, but you are passing them in the opposite way. So the api version fails, because the require(:post) fails, and the application version fails, because the data you are looking for is in `params[:post][:title], not params[:title].

Try swapping the bodies of the two update methods (with the appropriate modification, you don't want the application serving Json etc).

Andrew Williamson
  • 8,299
  • 3
  • 34
  • 62