not able to render form in rails association - ruby-on-rails

i created a project scaffold that has many to one association with stage scaffold now i created a task scaffold that has many to one association with stage scffold.
but i task form is not rendered i am getting error.
routes.rb
resources :projects do
resources :stages do
resources :tasks
end
end
Task form.html.erb
<%= form_with(model: task, url: [#stages, task], local: true) do |form| %>
<% if task.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(task.errors.count, "error") %> prohibited this task from being saved:</h2>
<ul>
<% task.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field columns large-6">
<%= form.label :task_name %>
<%= form.text_field :task_name %>
</div>
<div class="actions">
<%= form.submit 'Create', :class=>'button primary small' %>
</div>
<% end %>
model project.rb
has_many :stages
model stage.rb
belongs_to :project
has_many :tasks
model task.rb
belongs_to :stage

Rails can't find tasks_path in your application, because you moved tasks under projects and stages resources, so full path to tasks_path looks like projects_stages_tasks_path
So, you need to specify this url for given projects and stages
<%= form_with(model: task, url: projects_stages_tasks_path(#stages, #stages.project), local: true) do |form| %>

Related

not able to set project_id into databse in nested route

i have created a project scaffold with one to many association with responsibility. i am able to render responsibility form but i am not able to set project_id into responsibility table. i have created one to many association.
here are my code-
routes.rb
resources :projects do
resources :responsibilities
end
responsibility form.html.erb
<%= form_with(model: responsibility, url: [#project, responsibility], local: true) do |form| %>
<% if responsibility.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(responsibility.errors.count, "error") %> prohibited this responsibility from being saved:</h2>
<ul>
<% responsibility.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :responsibility_matrix %>
<%= form.text_field :responsibility_matrix %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
responsibilities_controller.rb
def new
#project = Project.find(params[:project_id])
#responsibility = Responsibility.new
end
Step by step
New app
rails new bookstore
Add scaffold author
rails g scaffold author name
Add scaffold book
rails g scaffold book name author:references
Updating routes
From
resources :books
resources :authors
To
resources :authors do
resources :books
end
Let's show link to new book in app/views/authors/show.html.erb, add
<%= link_to 'New book', new_author_book_path(#author) %> |
After create a first Author, and visiting http://localhost:3000/authors/1/books/new we have a erro that you have: NoMethodError in Books#new
undefined method `books_path'
To fix, first in BooksController add
before_action :set_author, only: [:new]
private
def set_author
#author = Author.find(params[:author_id])
end
And in app/views/books/_form.html.erb
<%= form_with(model: book, url:[#author, book], local: true) do |form| %>
Visiting again http://localhost:3000/authors/1/books/new
NameError in Books#new
undefined local variable or method `books_path'
Fix in app/views/books/new.html.erb
Change
<%= link_to 'Back', books_path %>
to
<%= link_to 'Back', author_books_path(#author) %>
Now we can render http://localhost:3000/authors/1/books/new
I think that here you got all you need

Nested forms in rails 4 and the fields_for method

I am also having problems with nested forms and Rails 4 (this seems to be quite common unfortunately). I have events which have requirements, the models are:
class Event < ActiveRecord::Base
enum type: [:lecture, :exercise, :tutorial]
has_one :requirement, dependent: :destroy
#accepts_nested_attributes_for :requirement
end
and
class Requirement < ActiveRecord::Base
belongs_to :event
end
There is essentially a one-to-one correspondence between those two.
Now I would like to create a new event together with the associated
requirement. I am using the following form:
<div class="container">
<%= form_for(#event) do |f| %>
<% if #event.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#event.errors.count, "error") %> prohibited this event from being saved:</h2>
<ul>
<% #event.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="container">
<%= f.select :type, Event.types.map { |key, value| [key.humanize, key] }%>
<%= f.text_field :number, placeholder: "1298035" %>
<% f.fields_for :requirement, #event.requirement do |fields| %>
<%= fields.check_box :beamer %><br />
<% end %>
<%= f.submit %>
</div>
<% end %>
</div>
As you can see I would like to have a checkbox indicating whether a beamer is required. The problem is that the fields_for block is never evaluated. Similar to these posts:
Rails 3: fields_for showing blank filed on Edit view
Helper "fields_for" not working
As far as I can tell the objects are created properly:
# GET /events/new
def new
#event = Event.new
#event.build_requirement
end
If I use puts I see that both objects are not nil and that the associations are correct.
I am kind of new to rails and I must say that I'm stymied. Any ideas?
You should uncomment accepts_nested_attributes_for :requirement in the Event model.
Update:
You should also include = in the fields_for.
<%= f.fields_for :requirement, #event.requirement do |fields| %>

NoMethodError in Rails when creating a new instance of model

I have a model that depends from another model, I have specified it like this in my routes.rb file
Rails.application.routes.draw do
resources :events do
resources :guests
get :whereabouts
end
devise_for :users, :controllers => { registrations: 'registrations' }
models/event.rb:
class Event < ActiveRecord::Base
belongs_to :user
has_many :guests
end
models/guest.rb:
class Guest < ActiveRecord::Base
belongs_to :event
end
When I access http://localhost:3000/events/2/guests/ it works properly but when I access http://localhost:3000/events/2/guests/new I get
undefined method `guests_path' for #<#<Class:0x00000004074f78>:0x0000000aaf67c0>
from line #1 of my views/guests/_form.html.erb file which is
<%= form_for(#guest) do |f| %>
<% if #guest.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#guest.errors.count, "error") %> prohibited this event from being saved:</h2>
<ul>
<% #guest.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I changed the paths to the proper ones since now guests_path should be event_guests_path, but I don't know where to change it in my form for it to work properly.
Any clue? Is my routing wrong?
Your routing is correct. But the guest object depends from the event one so you have to change the form to:
<%= form_for [#event, #guest] do |f| %>
...
<% end %>
you must have initialized the #event variable in the controller where you probably did something like:
#event = Event.find(params[:event_id])
#guest = #event.guests.build
From the docs:
For namespaced routes, like admin_post_url:
<%= form_for([:admin, #post]) do |f| %>
...
<% end %>
So, in your case, you probably want this:
<%= form_for([:event, #guest]) do |f| %>

undefined method `twitter_source_twitter_aggregation_methods_path' for #<#<Class:0xb982e10>:0xc104ef4>

I have 3 nested resources: sources, twitter_source and twitter_aggregation_methods.
The relationship of their respective models is as follows:
sources.rb
has_many :twitter_sources
has_many :rss_sources
twitter_source.rb
has_many :twitter_aggregation_methods
belongs_to :source
twitter_aggregation_method.rb
belongs_to :twitter_source
The config/routes.rb is set up as follows:
resources :sources do
resources :rss_sources
resources :twitter_sources do
resources :twitter_aggregation_methods
resources :influencer_trends do
resources :trends
end
end
end
When I try to add a new twitter_aggreggation_method I get the following error:
NoMethodError in TwitterAggregationMethods#new
Showing /home/notebook/work/abacus/app/views/twitter_aggregation_methods/_form.html.erb where line #1 raised:
undefined method `twitter_source_twitter_aggregation_methods_path' for #<#<Class:0xb982e10>:0xc104ef4>
My views/twitter_aggregation_methods/_form.html.erb is as follows:
<%= form_for([#twitter_source, #twitter_aggregation_method]) do |f| %>
<% if #twitter_aggregation_method.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#twitter_aggregation_method.errors.count, "error") %> prohibited this twitter_aggregation_method from being saved:</h2>
<ul>
<% #twitter_aggregation_method.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :twitter_source_id %><br>
<%= f.text_field :twitter_source_id, value: #twitter_source.id %>
</div>
<div class="field">
<%= f.label :aggregation_method %><br>
<%= f.text_field :aggregation_method %>
</div>
<div class="actions">
<%= f.submit %>
The error points to the first line of this partial.
Looking at the resources defined, twitter_source_twitter_aggregation_methods_path doesn't exist. Hence, the error.
You can do rake routes and check the prefixes to know what all routes exist.
From TwitterAggregationMethods#new you would be expecting to go to TwitterAggregationMethods#create, for that pass an instance of source in the form,
Replace
<%= form_for([#twitter_source, #twitter_aggregation_method]) do |f| %>
with
<%= form_for([#source, #twitter_source, #twitter_aggregation_method]) do |f| %>
and set #source in the TwitterAggregationMethods#new.

Can't get multi-model form to work

I have an Appointment model where each Appointment has a client_id. When an Appointment is created, I want the user to be able to type the client's name into an autocomplete field so a new Client is created if the name the user typed in doesn't already have a Client record. (I've done this exact same thing in other frameworks.)
Here's what my Appointment model looks like:
class Appointment < ActiveRecord::Base
has_many :appointment_services
belongs_to :client
accepts_nested_attributes_for :client
end
And here's what my form looks like:
<%= form_for(#appointment) do |f| %>
<% if #appointment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#appointment.errors.count, "error") %> prohibited this appointment from being saved:</h2>
<ul>
<% #appointment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.fields_for :client do |client_form| %>
<div class="field">
<%= client_form.label :name %>
<%= client_form.text_field :name %>
</div>
<% end %>
For some reason nothing inside <%= f.fields_for :client do... shows up on the screen. What am I doing wrong?
Try
<%= f.fields_for #client do |client_form| %>
and don't forget to initialize #client in your controller

Resources