not able to set project_id into databse in nested route - ruby-on-rails

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

Related

undefined method `project' for nil:NilClass

I have created project scaffold and stage scaffold with many to one association. Now I have added task scaffold with many to one association with stage scaffold. But I am not able to render task form correctly.
error
routes.rb:
resources :projects do
resources :stages do
resources :tasks
end
end
task form.html.erb
<%= form_with(model: task, url: projects_stages_tasks_path(#stages, #stages.project), 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">
<%= form.label :task_name %>
<%= form.text_field :task_name %>
</div>
<div class="actions">
<%= form.submit 'Create', :class=>'button primary small' %>
</div>
<% end %>
tasks_controller.rb
def index
#tasks = Task.all
end
def new
#task = Task.new
end
From what you wrote, I understand you're trying to create a task form as a nested resource. So I would do something like this: First of all, make sure you're setting #project and #stage variables in your tasks_controller:
before_action :set_project
before_action :set_stage
# ...
private
def set_project
#project = Project.find(params[:project_id])
end
def set_stage
#stage = #project.stages.find(params[:stage_id]) # Project#stages association is assumed to exist here
end
then, set your #task variable in the action itself, like this:
def new
#task = #stage.tasks.build # Stage#tasks association is assumed to exist here
end
then, in your view, you can use regular form, where you wouldn't have to specify the url on your own (well, I guess):
<%= form_with model: [#project, #stage, #task] do |f| %>
etc.

not able to render form in rails association

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| %>

Rails undefined method * for nil:NilClass

I am having an issue and I have done some reasearch, from my research I have found that the variable that is being used is empty, however I am unsure as to why it is empty, Maybe its something obvious to someone else?
I am trying to display a nested form on a page from another controller, I am used nested resources, Which I think might be my issue, but unsure how to resolve it.
Getting the following error:
undefined method `submission' for nil:NilClass
Structure of Project
Main Folders
-Members
--Questions
--Submissions
Concept:
Question - has_many - Submissions
Submission - Belongs_to - Question
Submission Model:
class Submission < ActiveRecord::Base
belongs_to :question
belongs_to :member
end
Question Model:
class Members::Question < ActiveRecord::Base
has_many :submissions
end
Submissions Controller:
def create
#question = Members::Question.find(params[:question_id])
#submission.member_id = current_member.id
#submission = #question.submissions.create(params[:submission].permit(:content, :question_id))
*Redirect Method Here *
end
In the form I am using the following method:
<%= form_for([#question, #question.submission.build]) do |f| %>
<% if #submission.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#submission.errors.count, "error") %> prohibited this submission from being saved:</h2>
<ul>
<% #submission.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And then to display the form on the show page of the question, I am using
<%= render 'members/submissions/form' %>
Routes:
namespace :members do
resources :questions, only: [:index,:show] do
resources :submissions
end
end
Any one any ideas where I am going wrong?
Any help is appreciated.
I have solved the problem, Thank you for the suggestions, I was using the wrong variable, I was using #question, When because its nested, the correct variable is #members_question
Submissions Controller
def create
#members_question = Members::Question.find(params[:question_id])
#submission = #members_question.submissions.create(params[:submission].permit(:content, :question_id))
#submission.member_id = current_member.id
end
_form.html.erb
<%= form_for([#members_question, #members_question.submissions.build]) do |f| %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

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 `premails_path' for #<#<Class:0x4fa8530>:0x52c1ec8>

I am trying to add a pre-launch sign-up email form on my pages index view. I made a form on my view, then created a controller, then made the model and table and ran the migration. Is this the right way to do it?
I am getting the following error:
NoMethodError in Pages#index
undefined method `premails_path' for #<#<Class:0x4fa8530>:0x52c1ec8>
on line:
<%= form_for(#premail) do |f| %>
from
<%= form_for(#premail) do |f| %>
<% if #premail.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#premail.errors.count, "error") %> prohibited this link from being saved:</h2>
My pages controller has the following:
class PagesController < ApplicationController
def index
#premail = Premail.new
end
end
My pages index view has the following:
<%= form_for(#premail) do |f| %>
<% if #premail.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#premail.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #premail.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :Email %><br />
<%= f.text_field :Email %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I generated the following model:
class Premail < ActiveRecord::Base
end
and the following db migrate table:
class CreatePremails < ActiveRecord::Migration
def change
create_table :premails do |t|
t.text :email
t.timestamps
end
end
end
What can I do differently to make this work?
Because you're loading this form on Pages#index, you'll benefit from using the url: argument like this:
<%= form_for #premail, url: pages_index_path do |f| %>
Update
From the Rails guide:
Resource-oriented style
In the examples just shown, although not indicated explicitly, we
still need to use the :url option in order to specify where the form
is going to be sent. However, further simplification is possible if
the record passed to form_for is a resource, i.e. it corresponds to a
set of RESTful routes, e.g. defined using the resources method in
config/routes.rb. In this case Rails will simply infer the appropriate
URL from the record itself. For example,
<%= form_for #post do |f| %> ... <% end %> is then equivalent to
something like:
<%= form_for #post, as: :post, url: post_path(#post), method: :patch,
html: { class: "edit_post", id: "edit_post_45" } do |f| %> ... <%
end %>
As you're using #premails instance var (which is an instance of the Premail class), your form_for helper will be trying to use a premails path. To use a pages path (as per your question), you'll need to manually set the url option

Resources