1
votes

Hello i'm new one in ruby on rails. I have strange problem. I use some tutorial and get error which i shouldn't get.

I have controller

class DiaryController < ApplicationController

before_action :authenticate_user!

respond_to :html, :xml, :json
respond_to :js, :only => [:create, :update, :destroy]

def create
@record = Record.create(record_params)
@record.userId=current_user.id

if request.xhr? || remotipart_submitted?
  sleep 1 if params[:pause]
  render :layout => false, :template => (params[:template] == 'escape' ? 'comments/escape_test' : 'diary/create'), :status => (@record.errors.any? ? :unprocessable_entity : :ok)
else
  redirect_to diary_path
end
end

def add
@record = Record.new
#respond_with(@record, :layout => false)
respond_with do |format|
  format.html { render :layout => ! request.xhr? }
end
end

# PUT /comments/1
# PUT /comments/1.xml
def update
  @record = Record.find(params[:id])
  respond_with do |format|
  format.html{ redirect_to @record }
end
end

def delete
  @comment = Comment.destroy(params[:id])
end

def edit
  @record = Record.find(params[:id])
end

def index
  @records = Record.where(userId: current_user.id)
end

private

def record_params
  params.require(:record).permit(:photo, :comment, :date, :photo_cache)
end

end

Have view

<h1 align="centre">
  Добавить запись
</h1>

<%= render 'form' %>

<%= link_to 'Отмена', diary_path, :id => 'cancel-button' %>

and

<%= form_for(@record, :remote => (params[:action] == 'add' ? true : false)) do |f| %>

<fieldset>
  <div class="field">
    <%= f.label :date, :class => 'required' %><br />
    <%= f.date_select :date %>
  </div>

  <div class="field">
    <%= f.label :comment %><br />
    <%= f.text_area :comment %>
  </div>

  <div class="field">
    <%= image_tag(@record.photo_url(:thumb)) if @record.photo? %><br />
    <%= f.label :photo %><br/>
    <%= f.file_field :photo %><br/>
    <%= f.hidden_field :photo_cache %>
  </div>

 </fieldset>

<table>
  <tr>
    <td>
      <div class="actions">
        <%= f.submit "Добавить", :data => {:'disable-with' => "Submitting..."} %>
      </div>
    </td>
    <td>
      <%= link_to 'Отмена', diary_path, :id => 'cancel-button' %>
    </td>
  </tr>
</table>

And get ActionView::Template::Error (undefined method `records_path' for #<#:0x000000054461c8>): error on "<%= form_for(@record, :remote => (params[:action] == 'add' ? true : false)) do |f| %>" line. Even records_path i did'n use.

I Have routes

devise_for :users
get 'welcome/index'
root 'welcome#index'
get 'diary' => 'diary#index'
get 'diary/add_record', to: 'diary#add', as: 'add_record'
post 'diary/add_record', to: 'diary#create'
get 'diary/edit_record/:id', to: 'diary#edit'
delete 'diary/edit_record/:id' => 'diary#delete

And and try to use add_record route. Maybe it would be better to use resources :records.But i want to figure out why my routes doesn't work.

view name "diary".

1
what path you want to use...? i m seeing u are using @record = Record.new, so rails will automatically map it to records controller create action. unless u add custom url in your form. - Rahul Singh
What is your view file name? - Pavan
I edit my question to clarify what you've asked - aleshko
Is your view name is diary.html.erb? - Pavan

1 Answers

3
votes

Because you're new to RoR, let me explain why you're receiving the error


form_for

form_for is the likely reason why you're receiving this error (oh, I just saw it actually states this is where the error occurs - sweet)

The problem you have is that form_for is meant as a way to render a form around an ActiveRecord object. It's mean to give some semi-persistence to the data, by using AR in both the new and create actions (allowing you to show the in-putted data on the form after submission)

When you pass an object to form_for, Rails automatically "builds" the form from the ActiveRecord object, one of the options it uses being the url

--

Routes

The problem you have is the object you pass to the form_for takes the model_name attribute to build the route. This means if you want to use the form_for method by just passing an object, it's going to look for routes pertaining directly to that object

If you don't have any [model]_path route set up, you'll likely receive the error you're getting. The fix firstly involves the routes, and secondly involves the controller:

#config/routes.rb
root 'welcome#index'
devise_for :users

resources :diary, path_names: { new: "add_record", create: "add_record", edit: "edit_record", destroy: "edit_record" }
resources :welcome, only: :index

This is down to the idea that Rails' routing structure is built around resources - every route you have should lead to a specific controller action. Whilst including custom actions is completely fine, you have to appreciate that the basis of the routing structure is to construct resourceful routing, which essentially means that Rails perceives every controller / model to have corresponding routes:

enter image description here

--

URL

The second thing to observe is the url of the form

If you have your routes set up as above, and if your routing structure differs from your model structure (different names), you'll want to use the following setup to define the url explicitly:

<%= form_for @record, url: your_custom_path do |f| %>