Aman Mehra
Aman Mehra

Reputation: 13

Convert resource routes in Rails to non-resource routes

I have implemented this simple form using non-db backed models. And I'm able to perform validations and showing form fields on it. But I have implemented this using resource. Now I want to learn about how to add more actions, apart from CRUD into this, and defining routes for them. Or if I want to stop using resources, and explicitly define paths for actions. How should I proceed with this?

My files:

Controller : new_forms_controller.rb

class NewFormsController < ApplicationController
  def new
   @form = NewForm.new
   flash[:notice] = nil
  end

  def index

  end

  def create
    @form = NewForm.new(params[:new_form])
    if @form.valid?
      flash[:notice] = "Successfully created recommendation."
      render :action => 'show'
    else
      render :action => 'new'
    end
  end

  def show

  end

end

Model : new_form.rb

class NewForm
  include ActiveModel::Validations
  include ActiveModel::Conversion
  include ActiveModel::Naming

  attr_accessor :title, :article, :content, :author

  validates :title, :article, :content, :author, :presence => true
  validates :title, :article => {:minimum => 5 }

  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end

end

Routes : route.rb

TestBranch::Application.routes.draw do
  resources :new_forms
  root :to => "new_forms#new"
end

New View

<%= content_for :title, "New Form" %>

<% if flash[:notice] %>
    <p><%= flash[:notice]%></p>
<% end %>

<%= form_for @form do |f| %>

    <% if @form.errors.any? %>
        <div id="error_explanation">
          <h2>
            <%= pluralize(@form.errors.count, "error") %> prohibited
            this article from being saved:
          </h2>
          <ul>
            <% @form.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
            <% end %>
          </ul>
        </div>
    <% end %>

    <p>
      <%= f.label :titleID %> <br/>
      <%= f.text_field :titleID %><br/>
    </p>
    <p>
      <%= f.label :articleID %><br/>
      <%= f.text_field :articleID %><br/>
    </p>
    <p>
      <%= f.label :content %><br/>
      <%= f.text_field :content %><br/>
    </p>
    <p>
      <%= f.label :author %><br/>
      <%= f.text_field :author %><br/>
    </p>

    <p><%= f.submit "Submit"  %></p>
<% end %>

Upvotes: 1

Views: 696

Answers (4)

max
max

Reputation: 102443

Adding extra routes to resources is pretty simple: Customizing the routes generated by resources is quite easy:

resources :users do
  collection do
    get :search
  end

  member do
    get :info
  end
end

This would give us:

GET /users/search => users#search
GET /users/:id/info => users#info

However before adding any more routes ask yourself if what you are trying to achieve does not actually match one of the existing CRUD actions - in nine times out of ten it does.

Upvotes: 1

eranavidor
eranavidor

Reputation: 66

You can define routes manualy using the match

match 'new_form' => 'new_form#index', :via => :get

This will match a get request to /new_form to the index action in new_form controller

Upvotes: 0

Arslan Ali
Arslan Ali

Reputation: 17812

resources basically saves you writing a lot of code and gives you ability to write the code yourself. Since, you have asked to explicitly define paths on your own, you can define them in following way:

In routes.rb,

get '/users' => 'users#index'
get '/users/:id' => 'users#show'
get '/users/new' => 'users#new'
post '/users' => 'users#create'
get '/users/:id/edit' => 'users#edit'
put '/users' => 'users#update'
delete '/users' => 'users#destroy'

These all lines are basically equivalent to resources :users. And additionally, you have asked about how to add more actions, and to define accordingly routes for them: first, you can take a look at what I wrote for resources :users, and second, you can take a look at guides for routes.

Upvotes: 1

RAJ
RAJ

Reputation: 9747

You need to add required actions to you controller and add corresponding routes to route.rb. Here is an example:

In route.rb:

TestBranch::Application.routes.draw do

  resources :new_forms do
    collection do
      get :new_action1    # will produce /new_forms/new_action1
      post :new_action2   # will produce /new_forms/new_action2
      delete :new_action3 # will produce /new_forms/new_action3
    end

    member do
      get :new_action4    # will produce /new_forms/:id/new_action4
      put :new_action5    # will produce /new_forms/:id/new_action5
      delete :new_action6 # will produce /new_forms/:id/new_action6
    end
  end

  root :to => "new_forms#new"
end

Controller: new_forms_controller.rb

class NewFormsController < ApplicationController
  ...

  def new_action1
    ...
  end

  def new_action2
    ...
  end

  def new_action3
    ...
  end

  def new_action4
    ...
  end

  def new_action5
    ...
  end

  def new_action6
    ...
  end

  ...
end

Upvotes: 0

Related Questions