Rails 3 has_one/has_many question - ruby-on-rails

I am writing an application that contains a database with several tables and joining tables and so forth... the two I am working with currently (and am stumped on) are my pages table and my templates table.
Now a page can contain only one template, but a template can have many pages.
Model for Page:
class Page < ActiveRecord::Base
has_one :template
accepts_nested_attributes_for :template
end
Model for Template:
class Template < ActiveRecord::Base
has_many :pages
end
When a user creates a page, I want them to be able to select a layout, but for some reason the select list is not showing up
HTML for show:
<%= form_for(#page) do |page| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this page from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= page.label "Page title" %><br />
<%= page.text_field :slug %>
</div>
<div class="field">
<%= page.label :active %>?<br />
<%= page.check_box :active %>
</div>
<%= page.fields_for :category do |cat| %>
<%= cat.label :category %>
<%= select :page, :category_id, Category.find(:all).collect{|c| [c.name, c.id] } %>
<% end %>
<%= page.fields_for :template do |temp| %>
<%= temp.label :template %>
<%= select :page, :template_id, Template.find(:all).collect{|t| [t.content, t.id] } %>
<% end %>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
Any reasons why the last select wouldn't show up?
Thanks in advance for all the help!
Edit:
All I had to do to fix the problem was put the Model logic in my controller and then call that object in the view and it worked
Controller:
def new
#page = Page.new
#categories = Category.find(:all)
#templates = Template.find(:all)
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #page }
end
end
View:
<div class="field">
<%= page.label :template %>
<%= page.select("template_id", #templates.collect { |t| [t.content, t.id] }, :include_blank => 'None') %>
</div>
Hope this helps someone else!

First page could "belongs to" template:
class Page < ActiveRecord::Base
belongs_to :template
accepts_nested_attributes_for :template
end
And instead of:
<%= page.fields_for :template do |temp| %>
<%= temp.label :template %>
<%= select :page, :template_id, Template.find(:all).collect{|t| [t.content, t.id] } %>
<% end %>
I would use a simple collection_select:
<%= page.select("template_id", Template.all.collect {|t| [ t.contet, t.id ] }) %>

Related

Prevent creating blank associations in nested attributes forms

I have a form with nested attributes that is sending to the Appointments controller which is creating instances of associated models called Prescriptions, Illnesses, Allergies, and Immunizations. The idea is that a doctor can fill out the form and can add information where needed, but isn't required to fill out everything (not every appointment requires a prescription).
Currently, the form sends out and creates new instances of all the associations with all the attributes blank or nil. I tried adding a validation requiring the presence of the attributes to save, but that creates an error and then nothing can save.
How can I submit one form and prevent it from creating instances of associated models if the fields for that model were empty?
Appointments Controller
def create
#appointment = current_user.appointments.new(appointment_params)
set_associations(#appointment, #patient)
if #appointment.save
Notification.create_appointment_notifications(#appointment, #health_profile)
flash[:notice] = "Your appointment has been saved."
redirect_to patient_health_profile_path(#patient, #health_profile)
else
flash[:notice] = "There was a problem saving your appointment, please try again."
redirect_to patient_health_profile_path(#patient, #health_profile)
end
end
private
def appointment_params
symptoms = params[:appointment][:symptoms].split(",")
#patient = Patient.find(params[:patient_id])
params.require(:appointment).permit(
:diagnosis, :referrals, :notes, :symptoms,
immunizations_attributes: [:name, :expiration_date],
illnesses_attributes: [:name, :status],
allergies_attributes: [:name, :status, :severity],
prescriptions_attributes: [:medicine, :dosage, :refills, :expiration_date]
).merge(symptoms: symptoms,
patient: #patient
)
end
def set_associations(appointment, patient)
appointment.illnesses.each do |illness|
illness.patient = patient
end
appointment.allergies.each do |allergy|
allergy.patient = patient
end
appointment.immunizations.each do |immunization|
immunization.patient = patient
end
appointment.prescriptions.each do |prescription|
prescription.patient = patient
prescription.doctor = current_user
end
end
def set_information
#patient = Patient.find(params[:patient_id])
#health_profile = HealthProfile.find(params[:id])
end
Nested Form
<%= form_for #appointment do |f| %>
<div>
<h4>Appointment</h4>
<div>
<%= f.label :Symptoms %>
<%= f.text_field :symptoms, id: "symptoms-input" %>
</div>
<div>
<%= f.label :Notes %>
<%= f.text_area :notes %>
</div>
<div>
<%= f.label :Diagnosis %>
<%= f.text_field :diagnosis %>
</div>
<div>
<%= f.label :Referrals %>
<%= f.text_area :referrals, id: "referrals-input" %>
</div>
</div>
<div>
<h4>Illnesses</h4>
<div>
<%= f.fields_for :illnesses do |illness| %>
<%= render "appointments/illness_fields", f: illness %>
<% end %>
</div>
<div>
<%= link_to_add_association '+ Illness', f, :illnesses, partial: "appointments/illness_fields" %>
</div>
</div>
<br>
<div>
<h4>Allergies</h4>
<div>
<%= f.fields_for :allergies do |allergy| %>
<%= render "appointments/allergy_fields", f: allergy %>
<% end %>
</div>
<div>
<%= link_to_add_association '+ Allergy', f, :allergies, partial: "appointments/allergy_fields" %>
</div>
</div>
<br>
<div>
<h4>Immunizations</h4>
<div>
<div>
<%= f.fields_for :immunizations do |immunization| %>
<%= render "appointments/immunization_fields", f: immunization %>
<% end%>
</div>
<div>
<%= link_to_add_association '+ Immunization', f, :immunizations, partial: "appointments/immunization_fields" %>
</div>
</div>
</div>
<br>
<div>
<h4>Prescriptions</h4>
<div>
<%= f.fields_for :prescriptions do |prescription| %>
<%= render "appointments/prescription_fields", f: prescription %>
<% end %>
</div>
<div>
<%= link_to_add_association '+ Prescription', f, :prescriptions, partial: "appointments/prescription_fields" %>
</div>
</div>
<%= hidden_field_tag(:patient_id, params[:patient_id]) %>
<%= hidden_field_tag(:id, params[:id]) %>
<div>
<%= f.submit :Submit %>
</div>
<% end %>
In your Appointments Model, add this line:
accepts_nested_attributes_for :illnesses, reject_if: :all_blank, allow_destroy: true

Facing issue in fetching state names using carmen gem

Hi I am using gem 'carmen-rails' in my app I am having this type of association
class Employee < ActiveRecord::Base
has_one :contact
has_one :permanent_address
accepts_nested_attributes_for :contact, :permanent_address
end
and in my employess_controller.rb I have define like this:
def subregion_options
render partial: 'subregion_select'
end
and in my routes :
resources :employees do
collection do
get 'subregion_options'
end
end
In my employees/new.html.erb
<%= form_for #employee do |f| %>
<label class="form_label">Email</label>
<%= f.text_field :email %>
<label class="form_label">Set Ex Employee</label>
<%= f.check_box :is_active %>
<%= f.fields_for :contact do |c| %>
<label class="form_label">Address 1</label>
<%= c.text_field :current_address1 %>
<%= c.country_select :country,:prompt => 'Select Country' %>
<%= render partial: 'subregion_select', locals: {parent_region: c.object.country} %>
<% end %>
<%= f.submit %>
<% end %>
in employees/_subregion_select.html.erb
<div id="order_state_code_wrapper">
<% parent_region ||= params[:parent_region] %>
<% country = Carmen::Country.coded(parent_region) %>
<% if country.nil? %>
<em>Please select a country above</em>
<% elsif country.subregions? %>
<%= subregion_select(:contact, :state_code, parent_region) %>
<% else %>
<%= text_field(:contact, :state_code) %>
<% end %>
</div>
In js file
$('select#employee_contact_attributes_country').change(function() {
selectWrapper = $('#order_state_code_wrapper');
countryCode = $(this).val();
url = "/employees/subregion_options?parent_region=" + countryCode;
selectWrapper.load(url);
});
But its not fetching any states. Please guide how to solve this. Thanks in advance.

Rails partial locals not working

I got
Class Question < ActiveRecord::Base
has_many :answers
end
and
class Answer < ActiveRecord::Base
belongs_to :question
end
My index action of question list all the questions and the basic CRUD actions.
<% #questions.each do |question| %>
And inside this loop I have another to show all answers to that question
<% question.answers.each do |answer| %>
After the action buttons I rendered the answer form partial
<%= render partial: 'answers/form' , question_id: question.id%>
But when them partial is rendered the question_id to the answer is aways 1.
I also tried
<%= render partial: 'answers/form', :locals => {:question_id => question.id} %>
Still no success.
This is the full index and form codes.
https://gist.github.com/CassioGodinho/7412866
(Please ignore the data-toggle on the Index, its also not working yet)
Its not a good practice to pass new instance variable as local to a partial
you can build the answer and then pass it as locals
<%= render partial: 'answers/form', :locals => {:answer => question.answers.build} %>
and in partial
<div class="answer_form">
<%= form_for(answer) do |f| %>
<% if answer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(answer.errors.count, "error") %> prohibited this answer from being saved:</h2>
<ul>
<% answer.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div>
<%= f.label :question %>
<%= f.collection_select(:question_id, #questions, :id, :title) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</div>
As Thomas Klemm showed it was easier to pass the #answer to the partial.
<%= render partial: 'answers/form', :locals => {:#answer => question.answers.build} %>

How to have a polymorphic model's partials associate to different things on the same page

Essentially, I have a binary voting system Like/Dislike. Thee class is called Like It has polymorphic associations to likeable:
class Like < ActiveRecord::Base
belongs_to :likeable, polymorphic: true
end
and we have the class Comment, which also has polymorphic associations to commentable and can be liked
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
has_many :likes, :as :likeable
end
We have the class Section, which can also be liked and commented on
class Section < ActiveRecord::Base
has_many :likes, as: :likeable
has_many :comments, as: commentable
end
However, on the page section#show I display the Section information, the section likes, and then the comments (from a comments/comments partial). Here is the Section#show view:
<h1><%= exercise.name %></h1>
<p><%= exercise.description %></p>
<%= render 'likes/like_button' %>
<%= render 'comments/comments' %>
<%= render 'comments/comment_form' %>
However, I want the ability to vote on each comment.
The following code is from the _comments.html.erb - What currently doesn't work is the rendering of the _like_button.html.erb because it doesn't apply to the comment at hand.
<% #comments.each do |comment| %>
<%= comment.content %>
<%= render 'likes/like_button' %>
<hr />
<% end %>
And here is the _like_button.html.erb partial
<% if #like.nil? %>
<%# No record of Like in table %>
<%= form_for [#likeable, Like.new] do |f| %>
<%= f.submit "Like" %>
<%= f.submit "Dislike" %>
<% end %>
<% else %>
<%# Marks current chosen option, if the opposite option is chosen, the record is updated to reflect the descion by the user %>
<%= form_for [#likeable, #like] do |f| %>
<% if #like.is_liked %>
Currently Liked!
<%= f.submit "Dislike" %>
<% else %>
<%= f.submit "Like" %>
Currently Disliked!
<% end %>
<% end %>
<% end %>
So ultimately, I just want to know how to make it possible to vote on a comment from within the Section#show view
Thanks!
Try this:
<% #comments.each do |comment| %>
<%= comment.content %>
<%= render 'likes/like_button', :like => comment.like, :likeable => comment %>
<hr />
<% end %>
<% if like.nil? %>
<%# No record of Like in table %>
<%= form_for [likeable, Like.new] do |f| %>
<%= f.submit "Like" %>
<%= f.submit "Dislike" %>
<% end %>
<% else %>
<%# Marks current chosen option, if the opposite option is chosen, the record is updated to reflect the descion by the user %>
<%= form_for [likeable, like] do |f| %>
<% if like.is_liked %>
Currently Liked!
<%= f.submit "Dislike" %>
<% else %>
<%= f.submit "Like" %>
Currently Disliked!
<% end %>
<% end %>
<% end %>

rails 3 associations error

I have a table pages and a table author. Each page belongs to one author. Created migrations for the tables and models as well. But getting this error while using it in form:
NoMethodError in Pages#new
Showing C:/rorapp/app/views/pages/_form.html.erb where line #1 raised:
undefined method `build' for nil:NilClass
Extracted source (around line #1):
1: <%= form_for(#page, #page.author.build) do |f| %>
2: <% if #page.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#page.errors.count, "error") %> prohibited this post from being saved:</h2>
Trace of template inclusion: app/views/pages/new.html.erb
Rails.root: C:/rorapp
Application Trace | Framework Trace | Full Trace
app/views/pages/_form.html.erb:1:in `_app_views_pages__form_html_erb___998576952_54480300'
app/views/pages/new.html.erb:2:in `_app_views_pages_new_html_erb__638997451_40207104'
Request
Parameters:
None
Show session dump
Show env dump
Response
Headers:
None
Here is my model file for author:
class Author < ActiveRecord::Base
has_one :page
end
And page model:
class Page < ActiveRecord::Base
validates :title, :presence => true
belongs_to :author
end
And here is the snippet of model form :
<%= form_for(#page, #page.author.build) do |f| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
Any ideas how to go ahead with it?
thanks
EDIT - 1
Here is my action method called new :
def new
#page = Page.new
#page.build_author
end
And here is the form it is rendering:
<%= form_for(#page) do |f| %>
<% if #page.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#page.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #page.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.label :author %><br />
<%= f.text_field :author %>
</p>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :reference %><br />
<%= f.select(:reference,[['google',1],['yahoo',2],['MSN',3],['Ask',4]]) %>
</p>
<%= f.submit "Submit" %>
<% end %>
EDIT - 2
Here is my controller code:
class PagesController < ApplicationController
def index
#total = Page.count
#pages = Page.find(:all)
end
def show
#page = Page.find(params[:id])
end
def new
#page = Page.new
#page.build_author
end
def create
#page = Page.new(params[:page])
if #page.save
redirect_to pages_path, :notice => "The data has been saved!"
else
render "new"
end
end
def edit
#page = Page.find(params[:id])
end
def update
#page = Page.find(params[:id])
if #page.update_attributes(params[:page])
redirect_to pages_path, :notice => "Your post has been updated!"
else
render "edit"
end
end
def destroy
#page = Page.find(params[:id])
#page.destroy
redirect_to pages_path, :notice => "Your page has been deleted!"
end
end
you need to add *#page.build_author* in the new action of pages controller.
def new
#page = Page.new
#page.build_author
respond_to do |format|
format.html # new.html.erb
format.json { render json: #page }
end
end
It should be #page.build_author instead of #page.author.build. But the logic of this still doesn't look right to me.

Resources