I didn't find anything related to my problem.
I have these models:
class Meal < ActiveRecord::Base
has_many :meal_ingredients
has_many :ingredients, through: :meal_ingredients
accepts_nested_attributes_for :ingredients, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :meal_ingredients
end
class Ingredient < ActiveRecord::Base
has_many :meal_ingredients
has_many :meals, through: :meal_ingredients
end
class MealIngredient < ActiveRecord::Base
belongs_to :meal
belongs_to :ingredient
end
In the meal_ingredient model I have a quantity column and I want to let the user set this quantity when creating a new meal with many ingredients. To allow that, I used the cocoon gem. And that's when the problem comes: I must set the ingredient_id and the meal_id to build the association with the quantity but I just hit the database when submiting the "Create Meal" buttom.
Part of the solution I thought is creating a fields_forinside the form and set an instance variable in the controller.
But how can I get these ids? I'm stuck.
class MealsController < ApplicationController
before_action :set_meal, only: [:edit, :update, :show]
autocomplete :ingredients, :name
def index
#meals = Meal.order(updated_at: :desc).paginate(:page => params[:page], :per_page => 4)
end
def show
end
def new
#meal = Meal.new
#qtd = MealIngredient.new
end
def create
#meal = Meal.new(meal_params)
#qtd = #meal.ingredients.map{|r| MealIngredient.new(quantity: params[:quantity], ingredient_id: r.id, meal_id: #meal)}
if #meal.save
flash[:success] = "Refeição criada com sucesso!"
redirect_to meals_path
else
render :new
end
end
def edit
end
def update
if #meal.update(meal_params)
flash[:success] = "Your meal was updated succesfully!"
redirect_to meal_path(#meal)
else
render :edit
end
end
private
def meal_params
params.require(:meal).permit(:name, :picture, ingredients_attributes: [:name, :unit, :carb, :prot, :fat])
end
def set_meal
#meal = Meal.find(params[:id])
end
end
This is what I got so far... I don't think the main problem is being caused by cocoon gem. I think it's about concepts...
The params
Parameters: {"utf8"=>"✓", "authenticity_token"=>"dTYOiz8+pwNfwt432qhy7Yuj0hSVksj0bsTzxp8vD6QaupIJueSO1ASDkwiOB92qCiLO33Ke61aUBGbyvGZJfA==", "meal"=>{"name"=>"tests", "ingredients_attributes"=>{"1449471543091"=>{"name"=>"uva", "unit"=>"und", "carb"=>"1", "prot"=>"1", "fat"=>"1", "_destroy"=>"false"}}}, "meal_ingredient"=>{"quantity"=>"14"}, "commit"=>"Create Meal"}
View
_form.html.erb
<div class = "row">
<div class= "col-md-10 col-md-offset-1">
<%= simple_form_for(#meal) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :name %>
</div>
<h3>ingredientes</h3>
<div id="ingredients">
<%= f.simple_fields_for :ingredients do |ingredient| %>
<%= render "ingredient_fields", :f => ingredient %>
<% end %>
</div>
<div class="form-actions">
<div><%= link_to_add_association 'adicionar ingrediente', f, :ingredients, :class => "btn btn-default" %></div>
<div><%= f.button :submit, class: "btn btn-success" %></div>
</div>
<% end %>
</div>
</div>
_ingredient_fields.html.erb
<%= render 'shared/errors', obj: #meal %>
<div class = "nested-fields">
<table class= "table">
<thead>
<tr>
<td>
<%= f.label "Nome" %>
</td>
<td>
<%= f.label "Unidade" %>
</td>
<td>
<%= f.label "Carbo" %>
</td>
<td>
<%= f.label "Prot" %>
</td>
<td>
<%= f.label "Gordura" %>
</td>
<td>
<%= f.label "Quantidade" %>
</td>
<td>
<%= f.label "kcal" %>
</td>
</tr>
</thead>
<tbody>
<tr>
<td scope="row" class="col-md-4">
<%= f.text_field :name, required: true, class: "form-control" %>
</td>
<td class="col-md-2">
<%= f.text_field :unit, required: true, class: "form-control" %>
</td>
<td class="col-md-1">
<%= f.text_field :carb, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= f.text_field :prot, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= f.text_field :fat, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= fields_for #qtd do |f| %>
<%= f.hidden_field :ingredient_id %>
<%= f.number_field :quantity, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
<% end %>
</td>
<td class="col-md-1">
</td>
<td class="col-md-1">
<%= link_to_remove_association "remove item", f, :class => "btn btn-danger" %>
</td>
</tr>
</tbody>
</table>
</div>
Following this tutorial and looking at the cocoon's demo app. It was easy to solve my problem, although I actually don't know exactly what I did here the
<%= link_to_add_association 'adicionar ingrediente', f, :meal_ingredients, 'data-association-insertion-node' => "#ingredients ol", 'data-association-insertion-method' => "append", :wrap_object => Proc.new {|quantity| quantity.build_ingredient; quantity }, :class => "btn btn-default" %>
I hate coding this way but this time I just went with the flow very carefully...
If someone has already used cocoon for that purpose and can explain better I - and the community - would appreciate :D
Changes made:
Model
class MealIngredient < ActiveRecord::Base
belongs_to :meal
belongs_to :ingredient
accepts_nested_attributes_for :ingredient, :reject_if => :all_blank
end
Controller
class MealsController < ApplicationController
before_action :set_meal, only: [:edit, :update, :show]
autocomplete :ingredients, :name
def index
#meals = Meal.order(updated_at: :desc).paginate(:page => params[:page], :per_page => 4)
end
def show
end
def new
#meal = Meal.new
end
def create
#meal = Meal.new(meal_params)
if #meal.save
flash[:success] = "Refeição criada com sucesso!"
redirect_to meals_path
else
render :new
end
end
def edit
end
def update
if #meal.update(meal_params)
flash[:success] = "Your meal was updated succesfully!"
redirect_to meal_path(#meal)
else
render :edit
end
end
private
def meal_params
params.require(:meal).permit(:name, :picture, :tcarb, :tprot, :tfat, :tkcal, meal_ingredients_attributes: [:quantity, ingredient_attributes: [:id, :name, :unit, :carb, :prot, :fat, :_destroy]])
end
def set_meal
#meal = Meal.find(params[:id])
end
end
Views
_form.html.erb
<div class = "row">
<div class= "col-md-10 col-md-offset-1">
<%= simple_form_for(#meal) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :name %>
</div>
<h3>ingredientes</h3>
<fieldset id="ingredients">
<ol>
<%= f.fields_for :meal_ingredients do |meal_ingredient| %>
<%= render "meal_ingredient_fields", :f => meal_ingredient %>
<% end %>
</ol>
<div class="form-actions">
<div><%= link_to_add_association 'adicionar ingrediente', f, :meal_ingredients, 'data-association-insertion-node' => "#ingredients ol", 'data-association-insertion-method' => "append", :wrap_object => Proc.new {|quantity| quantity.build_ingredient; quantity }, :class => "btn btn-default" %></div>
</div>
</fieldset>
<div class="form-actions">
<div><%= f.button :submit, class: "btn btn-success" %></div>
</div>
<% end %>
</div>
</div>
_meal_ingredient_fields.html.erb
<div class = "nested-fields">
<table class= "table">
<thead>
<tr>
<td>
<%= f.label "Nome" %>
</td>
<td>
<%= f.label "Unidade" %>
</td>
<td>
<%= f.label "Carbo" %>
</td>
<td>
<%= f.label "Prot" %>
</td>
<td>
<%= f.label "Gordura" %>
</td>
<td>
<%= f.label "Quantidade" %>
</td>
<td>
<%= f.label "kcal" %>
</td>
</tr>
</thead>
<tbody>
<tr>
<%= f.fields_for :ingredient do |fi| %>
<td scope="row" class="col-md-4">
<%= fi.text_field :name, required: true, class: "form-control" %>
</td>
<td class="col-md-2">
<%= fi.text_field :unit, required: true, class: "form-control" %>
</td>
<td class="col-md-1">
<%= fi.text_field :carb, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= fi.text_field :prot, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= fi.text_field :fat, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<% end %>
<td class="col-md-1">
<%= f.number_field :quantity, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
</td>
<td class="col-md-1">
<%= link_to_remove_association "remove item", f, :class => "btn btn-danger" %>
</td>
</tr>
</tbody>
</table>
</div>
I used cocoon also, and had some troubles setting it up. I think you have to realiaze that Rails is smarter then you think. You can easily just call save on the parameter string. Just make sure the parameters are all accepted. You will also need :id for ingredients_attributes for instance (and :_destroy, if you allow deletion as well). Oh, and loose the nested_attributes for your join table as well.
I think something like this should work:
def new
#meal = Meal.new
end
def create
#meal = Meal.new(meal_params)
if #meal.save
flash[:success] = "Refeição criada com sucesso!"
redirect_to meals_path
else
render :new
end
end
private
def meal_params
params.require(:meal).permit(:name, :picture, ingredients_attributes: [:id, :name, :unit, :carb, :prot, :fat, :_destroy])
end
If it doensn't, please post your views that contain the main form and the partials.
Related
I am new to spree and ruby on rails.While clicking the 'reviews' in spree back-end, it's throwing an error.
Thanks in Advance.
NoMethodError in Spree::Admin::Reviews#index
Showing - var/lib/gems/2.3.0/ruby/2.3.0/bundler/gems/spree_reviews-e51cae9627f9/app/views/spree/admin/reviews/index.html.erb where line #25 raised:
index.html.erb:
<% content_for :page_title do %>
<%= Spree.t('reviews') %>
<% end %>
<% render 'spree/admin/shared/product_sub_menu' %>
<% content_for :table_filter_title do %>
<%= Spree.t('search') %>
<% end %>
<% content_for :table_filter do %>
<div data-hook="admin_reviews_index_search">
<%= search_form_for [:admin, #search] do |f| %>
<div class="alpha three columns">
<div class="field">
<%= label_tag nil, Spree.t(:user) %><br />
<%= f.text_field :name_cont, :size => 25 %>
</div>
</div>
<div class="seven columns">
<div class="field">
<%= label_tag nil, Spree.t(:title) -%><br/>
<%= f.text_field :title_cont, :size => 25 -%>
</div>
</div>
<div class="four columns">
<div class="field">
<%= label_tag nil, Spree.t(:review) -%><br/>
<%= f.text_field :review_cont, :size => 25 -%>
</div>
</div>
<div class="two columns omega">
<div class="field">
<%= label_tag nil, Spree.t(:approval_status)-%><br/>
<%= f.select :approved_eq, [[Spree.t('all'), nil],
[Spree.t('approved_reviews'), true],
[Spree.t('unapproved_reviews'),false]] -%>
</div>
</div>
<div class="clear"></div>
<div class="form-buttons actions filter-actions" data-
hook="admin_reviews_index_search_buttons">
<%= button Spree.t(:search), 'icon-search' %>
</div>
<%- end -%>
</div>
<%- end -%>
<% paginate #reviews %>
<% if #reviews.any? %>
<table class="index">
<colgroup>
<col style="width: 25%;">
<col style="width: 10%;">
<col style="width: 10%;">
<col style="width: 20%;">
<col style="width: 15%;">
<col style="width: 17%;">
</colgroup>
<thead>
<tr>
<th><%= Spree.t('product') %></th>
<th><%= Spree::Review.human_attribute_name(:rating) %></th>
<th><%= Spree.t('feedback') %></th>
<th><%= Spree::Review.human_attribute_name(:user) %></th>
<th><%= Spree::Review.human_attribute_name(:created_at) %></th>
</tr>
</thead>
<tbody>
<%- #reviews.each do |review| -%>
<tr id="<%= dom_id review %>">
<td>
<% if review.product %>
<%= link_to review.product.name, product_path(review.product) %>
<% end %>
</td>
<td class="align-center">
<%= txt_stars(review.rating) %>
</td>
<td class="align-center">
<%= link_to "(#{review.feedback_stars}/#{review.feedback_reviews.size})", admin_review_feedback_reviews_path(review) %>
</td>
<td class="align-center">
<%= review.user_id ? link_to(review.user.try(:email), [:admin, review.user]) : Spree.t(:anonymous) %></p>
<p><%= Spree::Review.human_attribute_name(:ip_address) %>: <%= review.ip_address ? link_to(review.ip_address, "http://whois.domaintools.com/#{review.ip_address}") : '-' %></p>
</td>
<td class="align-center">
<%= l review.created_at, :format => :short %>
</td>
<td class="actions">
<%= link_to_with_icon 'check', Spree.t('approve'), approve_admin_review_url(review), :no_text => true, class: 'approve' unless review.approved %>
<%= link_to_edit review, :no_text => true, :class => 'edit' %>
<%= link_to_delete review, :no_text => true %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="no-objects-found">
<%= Spree.t(:no_results) %>
</div>
<% end %>
<%= paginate #reviews -%>
reviews_controller
class Spree::Admin::ReviewsController <
Spree::Admin::ResourceController
helper Spree::ReviewsHelper
def index
#reviews = collection
params[:q] ||= {}
#search = Spree::Review.ransack(params[:q])
#collection = #search.result.includes([:product, :user,
:feedback_reviews]).page(params[:page]).per(params[:per_page])
end
def approve
r = Spree::Review.find(params[:id])
if r.update_attribute(:approved, true)
flash[:notice] = Spree.t("info_approve_review")
else
flash[:error] = Spree.t("error_approve_review")
end
redirect_to admin_reviews_path
end
def edit
if #review.product.nil?
flash[:error] = Spree.t("error_no_product")
redirect_to admin_reviews_path and return
end
end
private
def collection
params[:q] ||= {}
#search = Spree::Review.ransack(params[:q])
#collection = #search.result.includes([:product, :user,
:feedback_reviews]).page(params[:page]).per(params[:per_page])
end
end
review.rb
class Spree::Review < ActiveRecord::Base
belongs_to :product, touch: true
belongs_to :user, :class_name => Spree.user_class.to_s
has_many :feedback_reviews
after_save :recalculate_product_rating, :if => :approved?
after_destroy :recalculate_product_rating
validates :name, presence: true
validates :review, presence: true
validates :rating, numericality: { only_integer: true,
greater_than_or_equal_to: 1,
less_than_or_equal_to: 5,
message: Spree.t('you_must_enter_value_for_rating') }
default_scope { order("spree_reviews.created_at DESC") }
scope :localized, ->(lc) { where('spree_reviews.locale = ?', lc) }
scope :most_recent_first, -> { order('spree_reviews.created_at DESC') }
scope :oldest_first, -> { reorder('spree_reviews.created_at ASC') }
scope :preview, -> { limit(Spree::Reviews::Config[:preview_size]).oldest_first }
scope :approved, -> { where(approved: true) }
scope :not_approved, -> { where(approved: false) }
scope :default_approval_filter, -> { Spree::Reviews::Config[:include_unapproved_reviews] ? all : approved }
def feedback_stars
return 0 if feedback_reviews.size <= 0
((feedback_reviews.sum(:rating) / feedback_reviews.size) + 0.5).floor
end
def set_search
#search=Product.search(params[:q])
end
def recalculate_product_rating
self.product.recalculate_rating if product.present?
end
end
Try to add result method after ransack:
#search = Spree::Review.ransack(params[:q]).result
I created a form with client and server side validations using the model and html5 as seen in the code. Everything is working fine, but everytime e click in the link "New Ingredient" and I fill the form below it doesn't work. Moreover, it only works if I refresh the page.
Why it's not working at first?
ingredient.rb
class Ingredient < ActiveRecord::Base
has_many :meal_ingredients
has_many :meals, through: :meal_ingredient
before_save { self.name = name.capitalize }
validates :name, presence: true, length: { minimum: 2, maximum: 25 }, uniqueness: true
validates :unit, presence: true validates :carb, :prot, :fat, numericality: true,
length: { minimum: 1, maximum: 5 }
end
/new.html.erb
<div class = "row">
<div class= "col-md-10 col-md-offset-1 well">
<table class= "table">
<%= form_for #ingredient do |f| %>
<thead>
<tr>
<td>
<%= f.label "Nome" %>
</td>
<td>
<%= f.label "Unidade" %>
</td>
<td>
<%= f.label "Carbo" %>
</td>
<td>
<%= f.label "Prot" %>
</td>
<td>
<%= f.label "Gordura" %>
</td>
<td>
<%= f.label "kcal" %>
</td>
</tr>
</thead>
<tbody>
<tr>
<td scope="row" class="col-md-5">
<%= f.text_field :name, required: true, class: "form-control" %>
</td>
<td class="col-md-3">
<%= f.text_field :unit, required: true, class: "form-control" %>
</td>
<td class="col-md-1">
<%= f.text_field :carb, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= f.text_field :prot, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
<%= f.text_field :fat, required: true, :pattern => '^\d+(\.\d+)*$', title: "Apenas números separados por pontos", class: "form-control" %>
</td>
<td class="col-md-1">
</td>
</tr>
</tbody>
<tfooter>
<tr>
<td class="pull-right">
<%= f.submit #ingredient.new_record? ? 'Create Ingredient' : 'Edit Ingredient', class: "btn btn-success" %>
</td>
<td>
<%= link_to "Voltar", ingredients_path, class: "btn btn-warning" %>
</td>
</tr>
</tfooter>
<% end %>
</table>
</div>
</div>
/ingredients_controller.rb
def new
#ingredient = Ingredient.new
end
def create
#ingredient = Ingredient.new(ingredient_params)
#ingredient.kcal = #ingredient.carb * 4 + #ingredient.prot * 4 + #ingredient.fat * 9
if #ingredient.save
flash[:success] = "Ingrediente criado com sucesso"
redirect_to ingredients_path
else
render 'new'
end
end
This is probably being caused by Turbolinks, which "speeds" up loading time by refreshing small parts of the DOM without reloading the whole entire page. As such, you'll need to trigger your script with an event that accounts for a partial refresh:
Try wrapping your JS in this:
var ready;
ready = function() {
# Your code here
};
$(document).ready(ready);
$(document).on("page:load", ready);
Here it is in CoffeeScript:
ready = ->
# Your code here
$(document).ready ready
$(document).on "page:load", ready
You can also disable Turbolinks from your "New Ingredient" link, which will cause the entire form page to be reloaded:
<%= link_to('New Ingredient', ..., data: { no_turbolink: true }) %>
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 %>
I am new to rails, And stuck in this problem from last two days
I have a student and student_parent model they have a one-to-many relationship i want to build database attribute through one object from form to datase.
controller's method
def new
#student = Student.new
1.times{ #student.student_parents.build }
.....
.....
end
Create Method:-
def create
#student = Student.new(params[:student])
respond_to do |format|
if #student.save
format.html { redirect_to Student, notice: 'Student was successfully created.' }
format.json { render json: #student, status: :created, location: #student }
else
format.html { render action: "new" }
format.json { render json: #student.errors, status: :unprocessable_entity }
end
end
end
Model:-
class Student < ActiveRecord::Base
include ErrorMessages
belongs_to :user
has_many :student_parents
attr_accessible :birth_date, :blood_group, :first_name, :gender, :last_name, :middle_name,
:school_name, :student_rollno, :email, :user_id, :student_parents_attributes
accepts_nested_attributes_for :student_parents
end
form:-
<%= simple_form_for #student, :html => { :class => 'form-horizontal' } do |f| %>
<div class="row-fluid">
<div class="span3">
<%= f.label :first_name, :class => 'control-label',:required => true %>
<%= f.text_field :first_name %>
</div>
<div class="span3">
<%= f.label :middle_name, :class => 'control-label'%>
<%= f.text_field :middle_name %>
</div>
<div class="span3">
<%= f.label :last_name, :class => 'control-label',:required => true %>
<%= f.text_field :last_name %>
</div>
</div>
<div class="control-group">
<label class = "control-label"> Email </label>
<div class="controls">
<%= f.text_field :email, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<label class = "control-label"> Birth Date <abbr title="required">*</abbr></label>
<div class="controls">
<%= f.text_field :birth_date, :class => 'text_field' ,'data-behaviour' => 'datepicker' %>
</div>
</div>
<% model_class = StudentParent %>
<div class="page-header">
<h4> Parent Information</h4>
</div>
<%= f.fields_for :student_parents do |student_parent| %>
<div class="row-fluid">
<!--<div class="span9">-->
<h5> Father Name </h5>
<div class="span3">
<%= student_parent.label :first_name, :class => 'control-label',:required => true %>
<%= student_parent.text_field :first_name %>
</div>
<div class="span3">
<%= student_parent.label :middle_name, :class => 'control-label'%>
<%= student_parent.text_field :middle_name %>
</div>
<div class="span3">
<%= student_parent.label :last_name, :class => 'control-label',:required => true %>
<%= student_parent.text_field :last_name %>
</div>
</div>
<div class="row-fluid">
<h5> Mother Name </h5>
<div class="span3">
<%= student_parent.label :first_name, :class => 'control-label',:required => true %>
<%= student_parent.text_field :first_name %>
</div>
<div class="span3">
<%= student_parent.label :middle_name, :class => 'control-label'%>
<%= student_parent.text_field :middle_name %>
</div>
<div class="span3">
<%= student_parent.label :last_name, :class => 'control-label',:required => true %>
<%= student_parent.text_field :last_name %>
</div>
</div>
<% end %>
<div class="form-actions">
<%= f.button :submit, :class => 'btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
students_path, :class => 'btn' %>
</div>
when submit it only build student information in student table and mother information in student_parent table. But it miss the parent information.
i have two models department and address and they are associated
with one another but when i use client side form validation address
model fields are not getting validated. The javascript for
validating associated model is not being generated.
Department model
class Department < ActiveRecord::Base
attr_accessible :agency_head, :agency_head_rank, :department_type_id, :fax, :name,
:phone, :address_attributes
validates :name , :length => { :minimum => 2 } , :presence => true
validates :department_type_id , :agency_head,:agency_head_rank,:phone,:fax, :presence => true
belongs_to :department_type
belongs_to :address, :class_name => "Address", :foreign_key => "address_id"
accepts_nested_attributes_for :address,:allow_destroy => true
end
Address model
class Address < ActiveRecord::Base
attr_accessible :state, :street1, :street2, :town, :zipcode, :county
validate :street1 ,:street2,:town,:state,:county,:zipcode ,:presence => true
has_one :department
end
view-page
<h1 id="form-title">Add New Department</h1>
<%=form_for #department ,:validate=>true do |f|%>
<div id="respond">
<% if #department.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#department.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #department.errors.full_messages.each do |msg| %>
<li>
<%= msg %>
</li>
<% end %>
</ul>
</div>
<% end %>
<p class="comment-form-author">
<label for="Department Name">Department Name</label><span class="required">*</span>
<%= f.text_field :name, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="Department Type">Department Type</label>
<%= f.collection_select :department_type_id, #dept_types, :id, :name, :prompt => true %>
</p>
<%= f.fields_for :address, #department.address ,:validate=> true do |addr| %>
<p class="comment-form-author">
<label for="Street1">Street 1</label>
<%= addr.text_field :street1 , :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="Street 2">Street 2</label>
<%= addr.text_field :street2, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="Town">Town</label>
<%= addr.text_field :town, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="State">State</label>
<%= addr.text_field :state, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="State">County</label>
<%= addr.text_field :county, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="Zip Code">Zip Code</label>
<%= addr.text_field :zipcode, :size => 30, 'aria-required' => 'true' %>
</p>
<% end %>
<p class="comment-form-author">
<label for="agency head">Agency Head</label><span class="required">*</span>
<%= f.text_field :agency_head, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="agency head rank">Agency Head Rank</label><span class="required">*</span>
<%= f.text_field :agency_head_rank, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="phone">Phone</label><span class="required">*</span>
<%= f.text_field :phone, :size => 30, 'aria-required' => 'true' %>
</p>
<p class="comment-form-author">
<label for="fax">Fax</label><span class="required">*</span>
<%= f.text_field :fax, :size => 30, 'aria-required' => 'true' %>
</p>
</div>
<div class="spacer">
<br/>
<center>
<%= f.button " Submit ", :id => 'my_login_form_button' %>
</center> </div> <% end %> </div> </div> </div> </div> </div>
You can use Jquery validate to validate your forms. It is much easier than doing it manually.
I find out my mistake use this one in address model.
validates :street1 ,:street2,:town,:state,:county,:zipcode ,:presence => true