Can't get multi-model form to work - ruby-on-rails

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

Related

Create several records at once in Rails

In my app users can create a set of codes to used in marketing activities. Therefore I want a form in which a user can type the amount of codes he want to create and then the system should generate that many codes and save them to the database.
code.rb
class Code < ActiveRecord::Base
belongs_to :form
attr_accessor :amount
end
_form.html.erb
<%= form_for [:customer, #code] do |f| %>
<% if #code.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#code.errors.count, "error") %> prohibited this code from being saved:</h2>
<ul>
<% #code.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :amount %><br>
<%= f.text_field :amount %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I want to do now is to tell the controller:
take :amount
create as many SecureRandom.hex(3) as :amount specifies
save all codes to database (column for the codes in the table is named "code")
However, I totally don't know how to achieve this...

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

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

Rails select NoMethodError in Messages#new

I'm trying to put on a select box the Users who will receive the message.
What we have is one table named Messages, one named Users and one named Friendships, on message table we have user_id (sender) and friend_id (receiver) both foreign key to Users ID.
And this is the error returning: undefined method `friend_id' for #Message:0x56f6238
That been said, I'm trying to vinculate all Friendships entries with current_user id and then using friend_id to search on Users table all users that current_user is able to send message.
Any help with this error? I'm really new on Ruby On Rails development.
If I'm missing some info, let me know.
Thanks in advance
On our application, the new_message_path renders one partial which contains the following:
<%= form_for(#message) do |f| %>
<% if #message.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#message.errors.count, "error") %> prohibited this message from being saved:</h2>
<ul>
<% #message.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label "Receiver" %><br />
<%= f.select :friend_id, Message.all.collect {|friendships| [ friendships.friend_id ] }, { include_blank: true } %>
</div><br>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And on our model named Message we have this:
class Message < ActiveRecord::Base
attr_accessible :content, :friend_id
validates_presence_of :content, :friend_id, presence => true
belongs_to :user
end

Resources