Nested form does not validate association model - ruby-on-rails

I'm using rails 3.2 with active record and sqlserver. I have a problem with nested forms. I have a model registration which has many registration details and each has a person associated.
Here is the model
class Registration < ActiveRecord::Base
set_table_name "dbo.EV_INSCRIPCIONES"
set_primary_key "Id"
belongs_to :category, :foreign_key => 'CategoriaId'
has_many :registrationDetails, :foreign_key => 'InscripcionEventoId'
#has_one :group
accepts_nested_attributes_for :registrationDetails
validates_associated :registrationDetails
validates :Refencia, :presence => true
#validates_presence_of :category_id
attr_accessible :registrationDetails, :category, :Eliminada, :FechaInscripcion, :CreationalDate, :Referencia, :PagoRegistrado, :Acreditado, :registrationDetails_attributes
#after_initialize :init
def init
write_attribute :Eliminada, false
write_attribute :Acreditado, false
write_attribute :PagoRegistrado, false
write_attribute :CreationalDate, DateTime.now
write_attribute :FechaInscripcion, DateTime.now
#write_attribute :Referencia, ''
end
def category_id
self.category.id unless category.nil?
end
def category_id=(id)
self.category = Category.find(id)
end
end
class RegistrationDetail < ActiveRecord::Base
set_table_name "dbo.EV_INSCRIPCION_DETALLE"
set_primary_key "Id"
belongs_to :registration, :foreign_key => 'InscripcionEventoId'
belongs_to :category, :foreign_key => 'CategoriaId'
belongs_to :person, :foreign_key => 'ParticipanteId', :primary_key => 'JUGADOR_ID'
attr_accessible :person, :category, :registration, :Eliminada, :person_attributes
accepts_nested_attributes_for :person
validates_associated :person
after_initialize :init
def init
write_attribute :Eliminada, false
end
end
class Person < ActiveRecord::Base
set_table_name "dbo.PKR_JUGADOR"
set_primary_key "JUGADOR_ID"
has_many :registrationDetails
validates_presence_of :CDNI, :CNOMBRES, :CAPELLIDO, :CSEXO,:CCIUDADRESIDENCIA, :DFECHANACIMIENTO
validates :CDNI, :length => { :minimum => 7, :maximum =>8 }
#validate :validate_birth_date
before_save :set_ids
def set_ids
if id.nil?
_id = Person.maximum(:JUGADOR_ID)
self.JUGADOR_ID = _id +1
write_attribute :CNROJUGADOR, _id+1
end
end
after_initialize :init
def init
write_attribute :TIPODOCUMENTO_ID, 1 if read_attribute(:TIPODOCUMENTO_ID).nil?
end
def full_name
self.surname + ", " + self.name
end
protected
def validate_birth_date
errors.add(:birth_date, 'must be a valid datetime') if ((Date.strptime(birth_date, "%d/%m/%Y") rescue ArgumentError) == ArgumentError)
end
end
My view
index.html.erb
<h1><%= t '.title', :name => #event.CNOMBRETORNEO %> </h1>
<%= render 'form_nested' %>
_form_nested
<%= form_for #registration, :url => {:controller => "registration", :action => "save"}, :html => {:class=> 'form-horizontal'} do |f| %>
<legend><%= t '.legend' %></legend>
<% if f.object.errors.any?%>
<div id="error_explanation">
<h3 class="text-error"><%= t '.has-errors' %></h3>
</div>
<% end %>
<input type="hidden" id="event_date" name="event_date" value="<%= #event.DDIAACTIVIDAD.strftime('%Y%m%d') %>" />
<input type="hidden" id="event_id" name="event_id" value="<%= #event.TORNEOPOKER_ID %>" />
<%= f.fields_for :registrationDetails do |d| %>
<%= render 'details_fields' , :f => d %>
<% end %>
<% has_error = f.object.errors.has_key? :category %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :category, :class=> 'control-label' %>
<div class="controls">
<%= f.hidden_field :category_id %>
<div class="btn-group" data-toggle-name="presenter_category_id" data-toggle="buttons-radio">
<%#categorias.each do |x| %>
<button value="<%= x.Id %>" type="button" class="btn" data-age-from="<%= x.FromAge %>" data-age-to="<%= x.ToAge %>"><%= x.Name %></button>
<%end %>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:category].join(", ")%></span>
<% end %>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary"><%= t '.save' %></button>
</div>
<%end%>
_detatails_fields
<%= f.object.errors.inspect %>
<%= f.fields_for :person do |p| %>
<%= render 'person_fields', :f => p %>
<% end %>
_person_fields
<%= f.hidden_field :id %>
<% has_error = f.object.errors.has_key? :CDNI %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :CDNI, :class=> 'control-label' %>
<div class="controls">
<div class="input-append">
<span class="add-on"><i class="icon-book"></i></span>
<%= f.text_field :CDNI, :class => 'input' %>
<div class="add-on" id="document_loader"><%= image_tag '6-0.gif' %></div>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:CDNI].join(", ")%></span>
<% end %>
</div>
</div>
<% has_error = f.object.errors.has_key? :DFECHANACIMIENTO %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :DFECHANACIMIENTO, :class=> 'control-label' %>
<div class="controls">
<div class="input-append">
<span class="add-on"><i class="icon-calendar"></i></span>
<%= f.text_field :DFECHANACIMIENTO, :class=>'input' %>
<span id="person_age" class="add-on"></span>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:DFECHANACIMIENTO].join(", ")%></span>
<% end %>
</div>
</div>
<% has_error = f.object.errors.has_key? :CNOMBRES %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :CNOMBRES, :class=> 'control-label' %>
<div class="controls">
<div class="input-append">
<span class="add-on"><i class="icon-user"></i></span>
<%= f.text_field :CNOMBRES,:class=>'input' %>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:CNOMBRES].join(", ")%></span>
<% end %>
</div>
</div>
<% has_error = f.object.errors.has_key? :CAPELLIDO %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :CAPELLIDO, :class=> 'control-label' %>
<div class="controls">
<div class="input-append">
<span class="add-on"><i class="icon-user"></i></span>
<%= f.text_field :CAPELLIDO,:class=>'input' %>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:CAPELLIDO].join(", ")%></span>
<% end %>
</div>
</div>
<div class="control-group">
<%= f.label :CTELEFONO, :class=> 'control-label' %>
<div class="controls">
<div class="input-append">
<span class="add-on"><i class="icon-certificate"></i></span>
<%= f.text_field :CTELEFONO,:class=>'input' %>
</div>
</div>
</div>
<% has_error = f.object.errors.has_key? :CSEXO %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :CSEXO, :class=> 'control-label' %>
<div class="controls">
<%= f.hidden_field :CSEXO %>
<div class="btn-group" data-toggle-name="presenter_sex" data-toggle="buttons-radio">
<button type="button" class="btn" value="M"><%= t '.masculine' %></button>
<button type="button" class="btn" value="F"><%= t '.femenine' %></button>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:CSEXO].join(", ")%></span>
<% end %>
</div>
</div>
<% has_error = f.object.errors.has_key? :CCIUDADRESIDENCIA %>
<div class="control-group<%= " error" if has_error %>">
<%= f.label :CCIUDADRESIDENCIA, :class=> 'control-label' %>
<div class="controls">
<div class="input-append">
<span class="add-on"><i class="icon-map-marker"></i></span>
<%= f.text_field :CCIUDADRESIDENCIA,:class=>'input' %>
</div>
<% if has_error %>
<span class="help-inline"><%=f.object.errors[:CCIUDADRESIDENCIA].join(", ")%></span>
<% end %>
</div>
</div>
And finally the controller
class RegistrationController < ApplicationController
def index
date = "20120729"
id = 1
#id = params[:event_id] unless params[:event_id].nil?
#date = params[:event_date] unless params[:event_date].nil?
#event = Event.find(date,id)
#groups = Group.all
#categorias = Category.where("DiaActividad = ? and TorneoId = ?", date, id)
#registration = Registration.new
#registration.registrationDetails.build( :person => Person.new)
end
def save
#registration = Registration.new(params[:registration])
if #registration.save
redirect_to :controller => 'home'
else
date = params[:event_date]
id = params[:event_id]
#event = Event.find(date,id)
#groups = Group.all
#categorias = Category.where("DiaActividad = ? and TorneoId = ?", date, id)
render :action => 'index'
end
end
end
What is happening? well first of all, the changes on any field are not saved, and the validations are not displayed. When i submit the form, it returns to the same page, and seems the form has errors but no one is displayed, and the data is lost.
Hope you can help me.
Thanks in advance

Well, I don´t Know why but I solved using resources.
In my routes.rb file
resources :registrations
Before I have something like this.
match 'registration/(:event_date)/(:event_id)' => 'registration#index'
match 'registration/save' => 'registration#save'
I think the problem was my custom routes. But i really don`t know.

Related

I am working on Ruby on rails but it is giving undefined method `errors' for nil:NilClass error

Don't know why my app is throwing error on the registration file.Plz let me know the error.Thank you very much
Error
Showing /home/punisher/Desktop/billboard/app/views/register/signup.html.erb where line #36 raised:
undefined method `errors' for nil:NilClass
Extracted source (around line #36):
<h1 class="Login-here">Register Here</h1>
<%= form_with model: #owner,url:register_path, local: true do |form| %>
<% if #owner.errors.any? %>
<div class="alert alert-danger">
<% #owner.errors.full_messages.each do |message| %>
<div> <%= message %> </div>
Register_controller
class RegisterController < ApplicationController
def new
#owner=Owner.new
end
def create
# render plain: "Thanks for registering!"
# render plain: params[:user]
#owner=Owner.new(owner_params)
if #owner.save
session[:owner_id] = #owner.id
redirect_to login_path
else
flash[:error] ="User Not Registered"
render :signup
end
end
private
def owner_params()
params.permit(:email, :company_name, :address, :contact_no, :password, :password_confirmation)
end
end
signup.erb.html
<body style = "background-color:rgb(92, 179, 196)">
<div class="tnavbar">
<div class="tlogo">
<%= image_tag('1.png', :class => "logoimg") %>
<h3 class="title"> Out of Home</h3>
</div>
<div>
<%= link_to "login", login_path, class:"home-btn"%>
</div>
</div>
<div class="container-fluid" style="margin-top:50px;">
<div class="row loginpagerow">
<div class="col-1">
</div>
<div class="logincol col-5 imagebox">
<h1 class="headinglogin">Bringing you the best of the best.</h1>
<%= image_tag('loginpageimage.png', :class => "img") %>
</div>
<div class="col-5 logincol loginbox">
<h1 class="Login-here">Register Here</h1>
<%= form_with model: #owner,url:register_path, local: true do |form| %>
<% if #owner.errors.any? %>
<div class="alert alert-danger">
<% #owner.errors.full_messages.each do |message| %>
<div> <%= message %> </div>
<% end %>
</div>
<% end %>
<div class="row" style="margin-top:30px">
<div style="width:45%; height:35vh; margin-left:25px;">
<%= form.email_field :email ,class: "form-control login-email-field signup-fields", placeholder:"Email" %>
<%= form.text_field :company_name ,class: "form-control login-email-field signup-fields", placeholder:"Company Name" %>
<%= form.text_field :address ,class: "form-control login-email-field signup-fields", placeholder:"Address" %>
</div>
<div style="width:45%; height:35vh; margin-left:25px;">
<%= form.telephone_field :contact_no ,class: "form-control login-email-field signup-fields", placeholder:"Contact No" %>
<%= form.password_field :password ,class: "form-control login-email-field signup-fields", placeholder:"password" %>
<%= form.password_field :password_confirmation,class: "form-control login-email-field signup-fields", placeholder:"Confirm password" %>
</div>
<div class="mb-3 login-input">
<%= form.submit "Signup" ,class: "sign-btn btn btn-primary"%>
</div>
</div>
<% end %>
</div>
<div class="col-1">
</div>
</div>
</div>
</body>
You have a app/views/register/signup.html.erb view and Rails expects signup method in your registrations_controller and is looking for #owner
instance method but you don't have signup method that's why it's raising an error because #owner is nil.
def signup
#owner = Owner.new(owner_params)
...
end

Ruby on Rails SOLR facets between 2 models

In my classifieds app , my "main" model is Classifieds but i have also implemented categorization so Categories has_many :classifieds
Also i have implemented my Categories with awesome_nested_set
And i have Solr search too!
In my sites Classifieds - index.html.erb i render the Classifieds and if search is used i render the corresponding Classifieds.
Now i have implemented a navbar which uses the Category model for navigation.
The navbar shows the Category.roots and the descendants of each root with a dropdown. This leads to the Category - show.html.erb ,where Classifieds are shown according to the Category they are in!
So the question is here:
In my Classifieds - index.html.erb i have successfully implemented Solr facets , which are used as filters but this only works when the user either Searches or just filters in the initial index! So in simple words when he interacts with the Classifieds Controller.
How can i preserve the facet functionality when the user uses the navbar , which means he then interacts with the Category controller
Models:
class Classified < ApplicationRecord
belongs_to :user
belongs_to :category
has_many :photos, dependent: :destroy, inverse_of: :classified
has_many :favorite_classifieds, dependent: :destroy
has_many :favorited_by , through: :favorite_classifieds , source: :user #for the favorite_by to work :source is needed
accepts_nested_attributes_for :photos
searchable do
text :title, :boost => 5
text :model , :created_month , :make , :make_country , :condition ,:treecat,:cat,:price #TO BE CHANGED TO CURRENCY FORMAT
time :created_at
string :treecat
string :price #TO BE CHANGED TO CURRENCY FORMAT
string :created_month
string :cat
string :make_country
string :condition
string :make
string :model
end
def cat
category.root.name
end
def treecat
category.name unless category.name == category.root.name
end
def created_month
created_at.strftime("%B")
end
end
class Category < ApplicationRecord
acts_as_nested_set
has_many :classifieds
end
Classifieds controller index action
def index
#search = Classified.search do
paginate(:page => params[:page] || 1, :per_page => 10)
order_by(:created_at , :desc)
fulltext params[:search]
with(:created_at)
active_model = with(:model ,params[:model]) if params[:model].present?
active_make = with(:make , params[:make]) if params[:make].present?
active_make_country = with(:make_country , params[:make_country]) if params[:make_country].present?
active_condition = with(:condition,params[:condition]) if params[:condition].present?
active_category = with(:cat,params[:cat]) if params[:cat].present?
active_subcategory = with(:treecat,params[:treecat]) if params[:treecat].present?
facet(:model)
facet(:make)
facet(:make_country)
facet(:condition)
facet(:cat , exclude: active_subcategory)
facet(:treecat)
end
#classifieds = #search.results
end
Categories controller show action
def show
#category = Category.find_by_id(params[:id])
end
Classifieds - index.html.erb
<div class="indexbox">
<div class="col-md-2 col-md-offset-1 visible-lg">
<div class="facets">
<h6>Μάρκα</h6>
<ul class="facetlist">
<% for row in #search.facet(:make).rows %>
<li>
<% if params[:make].blank? %>
<%= link_to(row.value, params.merge(:page => 1,:make => row.value).permit!) %> <small class="rowcount"><%= row.count %></small>
<% else %>
<strong><%= row.value %></strong> (<%= link_to "remove", :make => nil %>)
<% end %>
</li>
<% end %>
</ul>
<h6>Χώρα Κατασκευής</h6>
<ul class="facetlist">
<% for row in #search.facet(:make_country).rows %>
<li>
<% if params[:make_country].blank? %>
<%= link_to(row.value, params.merge(:page => 1,:make_country => row.value).permit!) %> <small class="rowcount"><%= row.count %></small>
<% else %>
<strong><%= row.value %></strong> (<%= link_to "remove", :make_country => nil %>)
<% end %>
</li>
<% end %>
</ul>
<h6>Κατάσταση</h6>
<ul class="facetlist">
<% for row in #search.facet(:condition).rows %>
<li>
<% if params[:condition].blank? %>
<%= link_to(row.value, params.merge(:page => 1,:condition => row.value).permit!) %> <small class="rowcount"><%= row.count %></small>
<% else %>
<strong><%= row.value %></strong> (<%= link_to "remove", :condition => nil %>)
<% end %>
</li>
<% end %>
</ul>
<h6>Κατηγορία</h6>
<ul class="facetlist">
<% for row in #search.facet(:cat).rows %>
<li>
<% if params[:cat].blank? %>
<%= link_to(row.value, params.merge(:page => 1,:cat => row.value).permit!) %> <small class="rowcount"><%= row.count %></small>
<% else %>
<strong><%= row.value %></strong> (<%= link_to "remove", :cat => nil %>)
<% end %>
</li>
<% end %>
</ul>
<h6>Κατηγορία</h6>
<ul class="facetlist">
<% for row in #search.facet(:treecat).rows %>
<li>
<% if params[:treecat].blank? %>
<%= link_to(row.value, params.merge(:page => 1,:treecat => row.value).permit!) %> <small class="rowcount"><%= row.count %></small>
<% else %>
<strong><%= row.value %></strong> (<%= link_to "remove", :treecat => nil %>)
<% end %>
</li>
<% end %>
</ul>
</div>
</div>
<% #classifieds.each do |f| %>
<% if !f.sold %>
<div class="center-div" id="index">
<div class="col-lg-12">
<div class="pull-right">
<div class="listingoptions">
<div class="col-md-3">
<p><%= link_to "", new_classified_message_path(:recipient_id => f.user_id , :classified_id => f.id), :class => "glyphicon glyphicon-envelope" , :style => "color:#EFCE7B" %></p>
<%if current_user.favorite_classifieds.collect(&:classified_id).include?(f.id) %>
<p><%= link_to "", favorite_classified_path(f, type: "unfavorite") , :class => "glyphicon glyphicon-heart" , :style => "color:#FF0000", method: :put %></p>
<%else%>
<p><%= link_to "", favorite_classified_path(f, type: "favorite") , :class => "glyphicon glyphicon-heart-empty" , :style => "color:#000000", method: :put %></p>
<%end%>
<p><%= link_to "", editlisting_path(f) , :class => "glyphicon glyphicon-flag" , :style => "color:#EB573B" %></p>
</div>
</div>
</div>
<%= link_to classified_path(f) , :class => "link" do %>
<div class="media">
<div class="mediabox">
<div class="media-left" href="#">
<!-- <img class="media-object" src="..." alt="Generic placeholder image">-->
<% if f.photos.first %>
<%= image_tag f.photos.first.image.url , :class => "media-object"%>
<%end%>
</div>
<div class="media-body">
<h5 class="media-heading"> <%= f.title %></h5>
<small><%= f.created_month %></small>
<% if f.category.parent_id? %>
<small><%= f.category.root.name %></small>
<%end%>
<small><%= f.category.name %></small>
<div class="price ">
<h5><%= f.price %> </h5>
</div>
</div>
</div>
</div>
</div>
</div>
<%end%>
<%end%>
<%end%>
<div class="center-div">
<div class="digg_pagination">
<%= will_paginate #classifieds , :previous_label => '<', :next_label => '>' %>
</div>
</div>
</div>
Categories show.html.erb
<div class="indexbox">
<div class="center-div" id="index">
<div class="categorytitle">
<h4>
<%= #category.root.name %>
<% unless #category.name == #category.root.name %>
<span> >> </span><%= #category.name %>
</h4>
<%end%>
</div>
</div>
<% #category.self_and_descendants.each do |desc| %>
<% desc.classifieds.each do |f|%>
<% if !f.sold %>
<div class="center-div" id="index">
<div class="col-lg-12">
<div class="pull-right">
<div class="listingoptions">
<div class="col-md-3">
<p><%= link_to "", new_classified_message_path(:recipient_id => f.user_id , :classified_id => f.id), :class => "glyphicon glyphicon-envelope" , :style => "color:#EFCE7B" %></p>
<%if current_user.favorite_classifieds.collect(&:classified_id).include?(f.id) %>
<p><%= link_to "", favorite_classified_path(f, type: "unfavorite") , :class => "glyphicon glyphicon-heart" , :style => "color:#FF0000", method: :put %></p>
<%else%>
<p><%= link_to "", favorite_classified_path(f, type: "favorite") , :class => "glyphicon glyphicon-heart-empty" , :style => "color:#000000", method: :put %></p>
<%end%>
<p><%= link_to "", editlisting_path(f) , :class => "glyphicon glyphicon-flag" , :style => "color:#EB573B" %></p>
</div>
</div>
</div>
<%= link_to classified_path(f) , :class => "link" do %>
<div class="media">
<div class="mediabox">
<div class="media-left" href="#">
<!-- <img class="media-object" src="..." alt="Generic placeholder image">-->
<% if f.photos.first %>
<%= image_tag f.photos.first.image.url , :class => "media-object"%>
<%end%>
</div>
<div class="media-body">
<h5 class="media-heading"> <%= f.title %></h5>
<small><%= f.created_month %></small>
<% if f.category.parent_id? %>
<small><%= f.category.root.name %></small>
<%end%>
<small><%= f.category.name %></small>
<div class="price ">
<h5><%= f.price %> </h5>
</div>
</div>
</div>
</div>
</div>
</div>
<%end%>
<%end%>
<%end%>
<%end%>
</div>
im a noob , i know there's stuff wrong with my indentation in html , sorry for that!
Ok i did it by nesting routes and taking some fields from the categories model.
resources :categories do
resources :classifieds do
end
end
Category model:
def nested_classifieds
Classified.where(category_id: self_and_descendants.select(:id))
end
def nested_categories
self_and_descendants
end
Classifieds controller
def index
if #category.present?
#classifieds = #category.nested_classifieds
nested_categories = []
#category.nested_categories.each do |f|
nested_categories << f.id
end
#search = Sunspot.search(Classified ) do
paginate(:page => params[:page] || 1, :per_page => 10)
order_by(:created_at , :desc)
fulltext params[:search]
with(:categoryid,nested_categories)
active_model = with(:model ,params[:model]) if params[:model].present?
active_make = with(:make , params[:make]) if params[:make].present?
active_make_country = with(:make_country , params[:make_country]) if params[:make_country].present?
active_condition = with(:condition,params[:condition]) if params[:condition].present?
active_category = with(:cat,params[:cat]) if params[:cat].present?
active_subcategory = with(:treecat,params[:treecat]) if params[:treecat].present?
active_pricerange = with(:price, params[:price]) if params[:price].present?
fulltext params[:prc]
facet :price
with(:price).less_than(1000)
facet(:model)
#facet(:model , exclude: active_condition)
facet(:make)
facet(:make_country)
facet(:condition)
facet(:cat)
facet(:treecat)
end
#classifieds = #search.results
else
#redirect_to '/'
##classified=#search.results
search
end
end

undefined method `strftime' for nil:NilClass - Comment Date

I am displaying the date when a comment is published:
<%= comment.created_at.strftime("%d %b %Y") %>
This works, except if the comment is not filled out correctly, and is submitted. If this occurs I get the error: undefined methodstrftime' for nil:NilClass` instead of my comment validations.
How to fix this, I am not sure?
Here's my code:
class CommentsController < ApplicationController
def create
#post = Post.friendly.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:name, `:email, :website, :body, :url))`
if #comment.errors.any?
render "posts/show"
else
redirect_to post_path(#post)
end
end
def destroy
#post = Post.friendly.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.destroy
redirect_to post_path(#post)
end
end
class Comment < ActiveRecord::Base
belongs_to :post
validates_format_of :email, :with => /#/
validates :name, presence: true, length: { minimum: 5}
validates :body, presence: true, length: { minimum: 5}
validates :body, presence: true, length: { minimum: 5}
def gravatar_url
stripped_email = email.strip
downcased_email = stripped_email.downcase
hash = Digest::MD5.hexdigest(downcased_email)
default_url = "https://s3-us-west-2.amazonaws.com/mirror-communications/assets/download.jpg"
"http://gravatar.com/avatar/#{hash}"
end
end
<!-- Post Comments Partial -->
<li>
<article class="comment">
<div class="user-avatar">
<%= image_tag comment.gravatar_url %>
</div>
<div class="comment-content">
<h5 class="name"><%= comment.name %></h5>
<div class="comment-meta comment-reply">
<span class="post-date"><%= comment.created_at.strftime("%d %b %Y") %></span>/<span class="comment-reply-link"><%= link_to comment.website.try(:remove, /.*\/\//), url_for(comment.website), target: '_blank', class: "comment-reply" %></span>
</div>
<p><%= comment.body %></p>
</div>
</article>
<!-- Form Partial -->
<%= form_for([#post, #post.comments.build]) do |f| %>
<% if #comment && #comment.errors.any? %>
<div id="error_explanation" class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h2><%= pluralize(#comment.errors.count, "error") %> Your comment could not be submitted:</h2>
<ul>
<% #comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<form class="comment-form">
<div class="row">
<div class="column width-4">
<%= f.text_field :name, class: "form-name form-element", placeholder: "Name*", :tabindex => 1 %>
</div>
<div class="column width-4">
<%= f.email_field :email, class: "form-email form-element", placeholder: "Email* (not displayed)", :tabindex => 3 %>
</div>
<div class="column width-4">
<%= f.url_field :website, class: "form-website form-element", placeholder: "Website", :tabindex => 4 %>
</div>
</div>
<div class="row">
<div class="column width-12">
<%= f.text_area :body, class: "form-message form-element", placeholder: "Message*", :tabindex => 5 %>
<%= f.submit class: "form-submit button medium bkg-black bkg-hover-turquoise color-white color-hover-white no-margin-bottom" %>
</div>
</div>
</form>
</div>
<% end %>
<!-- Posts Show -->`
<div class="post-comments">
<h3 class="comments-title">
<% if #post.comments.count < 2 %>
<%= #post.comments.count %> Comment</h3>
<% else %>
<%= #post.comments.count %> Comments</h3>
<% end %>
<div class="comments">
<ul class="comment-list">
<%= render #post.comments %>
</ul>
</div>
</div>
I think you have not populated local variable comment properly.
try this,
comment.created_at.strftime("%d %b %Y") if comment and comment.created_at

Rails 4 Nested Attributes has Unpermitted parameter error

Below is my api model:
class Api < ActiveRecord::Base
validates_presence_of :name
belongs_to :service
has_many :statuses
accepts_nested_attributes_for :statuses, reject_if: proc { |attributes| attributes['name'].blank? }
end
Below is my description model:
class Description < ActiveRecord::Base
validates_presence_of :value
belongs_to :status
end
Below is my status model:
class Status < ActiveRecord::Base
belongs_to :api
has_many :descriptions
accepts_nested_attributes_for :descriptions, reject_if: proc { |attributes| attributes['value'].blank? }
end
And below is my new and create action of controller:
def new
#api = Api.new
#status = #api.statuses.new
#status.descriptions.new
end
def create
#api = Api.new(api_params)
if #api.save
flash[:info] = request.original_url + ".do?apiname=" + "#{#api.name}"
redirect_to root_path
else
#api.statuses.new
render :new
end
private
def api_params
params.require(:api).permit(:name, statuses_attributes: [:name, descriptions_attributes:[:value]])
end
Below is my new template:
<div class="form-horizontal">
<%= form_for #api, :url => commons_path do |f| %>
<div class="form-group">
<%= f.label :name, "API Name", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= f.text_field :name, class: "form-control" %>
</div>
</div>
<%= f.fields_for :statuses do |status| %>
<div class="form-group">
<%= status.label :name, "Status", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= status.text_field :name, class: "form-control" %>
</div>
</div>
<%= f.fields_for :description do |description| %>
<div class="form-group">
<%= description.label :value, "Body", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= description.text_area :value, class: "form-control", rows: 12, cols: 65 %>
</div>
</div>
<% end %>
<% end %>
<%= f.submit("Create Data", class: 'btn btn-primary col-sm-offset-2') %>
<%= link_to "Cancel", root_path, class: "btn btn-danger" %>
<% end %>
After I create new data.It seems like only description's value did not save to my data base. and find an error "Unpermitted parameter: description" in my console.
Any one know what happen?
<div class="form-horizontal">
<%= form_for #api, :url => commons_path do |f| %>
<div class="form-group">
<%= f.label :name, "API Name", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= f.text_field :name, class: "form-control" %>
</div>
</div>
<%= f.fields_for :statuses do |status| %>
<div class="form-group">
<%= status.label :name, "Status", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= status.text_field :name, class: "form-control" %>
</div>
</div>
<%= status.fields_for :descriptions do |description| %>
<div class="form-group">
<%= description.label :value, "Body", class: "col-sm-2 control-label" %>
<div class="col-sm-8">
<%= description.text_area :value, class: "form-control", rows: 12, cols: 65 %>
</div>
</div>
<% end %>
<% end %>
<%= f.submit("Create Data", class: 'btn btn-primary col-sm-offset-2') %>
<%= link_to "Cancel", root_path, class: "btn btn-danger" %>
<% end %>

Using accepts_nested_attributes_for on a join table with its own attributes - Duplicate rows

I have the following three models (Rails 2.3.8)
class Outbreak < ActiveRecord::Base
has_many :incidents, :dependent => :destroy
has_many :locations, :through => :incidents
accepts_nested_attributes_for :incidents, :allow_destroy => true
accepts_nested_attributes_for :locations, :allow_destroy => true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end
class Incident < ActiveRecord::Base
belongs_to :outbreak
belongs_to :location
end
class Location < ActiveRecord::Base
has_many :incidents
has_many :outbreaks, :through => :incidents
accepts_nested_attributes_for :incidents, :allow_destroy => true
end
The parameters from the form seem to be ok
"outbreak"=>{
"locations_attributes"=>{"0"=>{"lon"=>"-1.39", "placename"=>"wetwe", "hpu_id"=>"15", "postcode"=>"so1 1aa", "region_id"=>"10", "address_1"=>"", "town"=>"Bargate", "address_2"=>"", "address_3"=>"", "lat"=>"50.89"}},"incidents_attributes"=>{"0"=>{"subtype_id"=>"7", "category_id"=>"1", "detail"=>"", "subcategory_id"=>"2"}}
}
But when the Outbreak is saved 3 rows are created in the Incidents table (the join table) and a single row in the Outbreak and Location tables.
The rows in the Incidents table are not fully populated from the params as follows:
id outbreak_id location_id category_id subcategory_id subtype_id detail created_at updated_at
57 23 NULL 1 2 7 2010-11-25 14:45:18.385905 2010-11-25 14:45:18.385905
58 23 27 NULL NULL NULL NULL 2010-11-25 14:45:18.39828 2010-11-25 14:45:18.39828
59 23 27 NULL NULL NULL NULL 2010-11-25 14:45:18.403051 2010-11-25 14:45:18.403051
This must be due to the either the format of the parameters or the multiple accepts_nested_attributes_for methods - how do I have just a single row being entered in the Incidents table with all of the parameters information?
Second time so far this week I've answered my own question ^^ that'll teach me to put more effort in before giving up and posting on the net for help,
Still after looking at my original question I didn't include enough information to answer it properly - the issue (apart from the set up of the models) was down to the Outbreak constructor in the Outbreak controller new method,
Original Outbreaks_controller
def new
#outbreak = Outbreak.new
#outbreak.risks.build
//links locations directly to Outbreak instead of through Incidents
#outbreak.locations.build
#outbreak.incidents.build
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #outbreak }
end
end
Revised Outbreaks_controller
def new
#outbreak = Outbreak.new
#outbreak.risks.build
//builds Incidents then a Location through that incident
#outbreak.incidents.build.build_location
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #outbreak }
end
end
Changes to the three models
class Outbreak < ActiveRecord::Base
has_many :incidents, :dependent => :destroy
has_many :locations, :through => :incidents
accepts_nested_attributes_for :incidents, :allow_destroy => true
end
class Incident < ActiveRecord::Base
belongs_to :outbreak
belongs_to :location
accepts_nested_attributes_for :location, :allow_destroy => true
end
class Location < ActiveRecord::Base
has_many :incidents
has_many :outbreaks, :through => :incidents
end
This seems to work ok - also posted the create action and main form
The create action only needs the nested params provided for :outbreak (the models do the work).
def create
#outbreak = Outbreak.new(params[:outbreak])
#outbreak.user_id = current_user.id
respond_to do |format|
if #outbreak.save
flash[:notice] = 'Outbreak was successfully created.'
format.html { redirect_to(#outbreak) }
format.xml { render :xml => #outbreak, :status => :created, :location => #outbreak }
else
format.html { render :action => "new" }
format.xml { render :xml => #outbreak.errors, :status => :unprocessable_entity }
end
end
end
The outbreak form is pretty long so I've cut it down to the two sections mentioned (although there's probably more attributes and fields here than is need to get an idea).
An example of the HTML element id for the nested fields can be found at the bottom in the Javascript observe_field helper. A post I made on AJAX updates of nested_attributes_for partials might also be useful AJAX update of accepts_nested_attributes_for
<% form_for(#outbreak, :html => {:multipart => true}) do |form| %>
<%= form.error_messages %>
<div id="tabs">
<ul>
<li >Outbreak</li>
<li >Location</li>
</ul>
<div id="tabs_b">
<fieldset id="b" class="form_div">
<legend>Outbreak</legend>
<fieldset>
<legend>References</legend>
<div class="left_form">
<%= form.label :user_reference %>
</div>
<div class="right_form">
<%= form.text_field :user_reference %>
</div>
<div style="clear:both;"></div>
</fieldset>
</fieldset>
</div>
<div id="tabs_c">
<fieldset id="c" class="form_div" >
<legend>Location</legend>
<div id="location_error"></div>
<fieldset>
<legend>Setting</legend>
<% form.fields_for :incidents do |incident_form| %>
<div class="left_form">
<%= incident_form.label :category_id %>
</div>
<div class="right_form">
<div id="incident_category_select">
<%= render :partial => 'category_select', :locals => {:categories => #categories, :incident_form => incident_form} %>
</div>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= incident_form.label :subcategory_id %>
</div>
<div class="right_form">
<div id="incident_subcategory_select">
<%= render :partial => 'subcategory_select', :locals => { :subcategories => #subcategories, :incident_form => incident_form } %>
</div>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= incident_form.label :subtype_id %>
</div>
<div class="right_form">
<div id="incident_subtype_select">
<%= render :partial => 'subtype_select', :locals => { :subtypes => #subtypes, :incident_form => incident_form } %>
</div>
</div>
<div style="clear:both;"></div>
<div id="cuisine_div">
<% if #outbreak.outbreak_type == "FOODBORNE" %>
<div class="left_form">
<%= label :incident, :cuisine_id %>
</div>
<div class="right_form">
<% cuisine_select = (#incident != nil ? #incident.cuisine_id.to_i : '') %>
<%= incident_form.select( :cuisine_id, "<option value='' >Please select</option>" + options_from_collection_for_select(#cuisines, :id, :name, cuisine_select)) %>
</div>
<% end %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= incident_form.label :detail %>
</div>
<div class="right_form">
<%= incident_form.text_field :detail %>
</div>
</fieldset>
<fieldset>
<legend>Details</legend>
<% incident_form.fields_for :location do |location_form| %>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :placename %>
</div>
<div class="right_form">
<%= location_form.text_field :placename %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :address_1 %>
</div>
<div class="right_form">
<%= location_form.text_field :address_1 %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :address_2 %>
</div>
<div class="right_form">
<%= location_form.text_field :address_2 %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :address_3 %>
</div>
<div class="right_form">
<%= location_form.text_field :address_3 %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :town %>
</div>
<div class="right_form">
<%= location_form.text_field :town %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :postcode %>
</div>
<div class="right_form">
<%= location_form.text_field :postcode %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :region_id %>
</div>
<div class="right_form" >
<% region_select = (#location != nil ? #location.region_id.to_i : '') %>
<%= location_form.select(:region_id, "<option value=''>Select a region</option>" + options_from_collection_for_select(#regions, :id, :name, region_select)) %>
</div>
<div style="clear:both;"></div>
<div class="left_form">
<%= location_form.label :hpu_id %>
</div>
<div class="right_form" >
<% hpu_select = (#location != nil ? #location.hpu_id.to_i : '') %>
<%= location_form.select(:hpu_id, "<option value=''>Select a HPU</option>" + options_from_collection_for_select(#hpus, :id, :name, hpu_select)) %>
</div>
<div style="clear:both;"></div>
<%= location_form.hidden_field :lon, :value => '' %>
<%= location_form.hidden_field :lat, :value => '' %>
<%= hidden_field_tag :postcode_error, :value => '0' %>
<% end %>
</fieldset>
<% end %>
</fieldset>
</div>
</div>
<% end %>
<div style="clear: both; margin: 10px;"></div>
<%= observe_field(:outbreak_incidents_attributes_0_location_attributes_postcode,
:url => { :controller => :locations, :action => :find_lonlat },
:on => "onchange",
:loading => "Element.show('loader')",
:success => "Element.hide('loader')",
:with => "'postcode=' + encodeURIComponent($('outbreak_incidents_attributes_0_location_attributes_postcode').value)" ) %>

Resources