NoMethodError in Rails when creating a new instance of model - ruby-on-rails

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

Related

Error of unidentified method in form - Ruby on rails

So I did find similar questions but could not quite find a good answer, so here's my question
I keep getting this method error when trying to go into localhost:3000/clients/1/precios/new (the error comes from the _form.html.erb)
First of all routes.rb
Rails.application.routes.draw do
#resources :precios
#resources :catalogos
resources :clients do
#resources :catalogs, shallow: true
resources :remissions, shallow: true
resources :catalogos
resources :precios
end
resources :catalogs do
resources :products, shallow: true do
resources :prices, shallow: true
end
end
devise_for :users
devise_scope :user do
get '/users/sign_out ' => 'devise/sessions#destroy'
end
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root 'home#index', as: 'home'
get 'new' => 'clients#new', as: 'alta_cliente'
get 'clients#index' => 'clients#index', as: 'lista_clientes'
get 'remissions#index' => 'remissions#new', as: 'nueva_remision'
end
And this is the error I keep getting
undefined method `precios_path' for #<#<Class:0x000000000d1f7018>:0x000000000a18fc90>
Did you mean? price_path
Extracted source (around line #2):
<div class="alta-form-container">
<%= form_with(model: precio, local: true) do |form| %> (Error in this line)
<% if precio.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(precio.errors.count, "error") %> prohibited this precio from being saved:</h2>
And this is my _form.html.erb
<div class="alta-form-container">
<%= form_with(model: precio, local: true) do |form| %>
<% if precio.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(precio.errors.count, "error") %> prohibited this precio from being saved:</h2>
<ul>
<% precio.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :precio %>
<%= form.number_field :precio %>
</div>
<div class="field">
<%= form.label :client_id %>
<%= form.text_field :client_id %>
</div>
<div class="field">
<%= form.label :catalogo_id %>
<%= form.text_field :catalogo_id %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
</div>
What is it that I need to change in the form?
You have following code in routes
resources :clients do
resources :precios
end
So you need both clients as well as precios object, try following
<%= form_with(model: [client, precio], local: true) do |form| %>
Note:- You should have access to the client object in _form.html.erb

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

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.

Rails: create two nested items in controller but only one shows in the view

Consider the following:
customer.rb
module Refinery
class Customer < Refinery::Core::BaseModel
has_many :users, :class_name => "Refinery::User"
accepts_nested_attributes_for :users
end
end
end
user_decorator.rb
Refinery::User.class_eval do
belongs_to :customer, :class_name => 'Refinery::Customer'
end
customer_controller.rb
module Refinery
class UsersController
def new
#customer = ::Refinery::Customer.new
# tried using build here as well with no sucess
#owner = #customer.users.new
#inputer = #customer.users.new
# raise #customer.users.length.to_yaml => returns 2 so that works!
end
end
end
new.html.erb
<%= form_for #customer do |f| %>
<% if #customer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#customer.errors.count, "error") %> need to be corrected before continuing:</h2>
<ul>
<% #customer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<!-- company fields here -->
<%= fields_for :users do |user| %>
<div>
<%= user.label :first_name %>
<%= user.text_field :first_name %>
</div>
<div>
<%= user.label :last_name %>
<%= user.text_field :last_name %>
</div>
<!-- more user fields here etc -->
<% end $>
<% end %>
When I view this page only one user shows up. The ids for the fields look like this also:
<div>
<label for="users_last_name">Last name</label>
<input id="users_last_name" name="users[last_name]" size="30" type="text">
</div>
I think there should be some kind of index in there right? (i.e. 0, 1, 2 etc for as if iterating over an array.
What am I doing wrong?
You missed the
f.fields_for
Just add it and it should work

why does this form not take data from a model?

I would like to capture email addresses with this form:
I have decided to create a model only for this and use the views and controller for a different model that is serving only static assets (think: newsletter sign-up).
<%= form_for (#signup) do |f| %>
<% if #signup.errors.any? %>
<div id="error_explanation">
<p><%= pluralize(#signup.errors.count, "error") %> prohibited this post from being saved:</p>
<ul>
<% #signup.errors.full_messages.each do |user| %>
<li><%= user %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email_address %><br />
<%= f.email_field_tag :email_address %>
</div>
<div class="actions">
<%= f.submit %>
</div>
How do I get this form to work? I get undefined method signups_path for #<#<Class:0x00000004f1feb0>:0x00000004f09a98> exception, which is understandable (its looking for a SignupsController by convention).
But I want the form to display in a separate controller I call PagesController and send it to the Signup model.
Additional Info:
I tried passing url: pages_path in the form and get the same exception.
# view inside PagesController
<div class="four columns">
<%= render 'form' %>
</div>
#stub of model
class PagesController < ApplicationController
def index
#signup = Signup.new
end
def create
#signup = Signup.new(params[:signup])
end
end
try:
<%= form_for #sighup, :url => {:controller => :pages, :action => :index} do |f| %>
and I hope you didn't forget the
<% end %>

Resources