Multiselect is not saving - ruby-on-rails

I`m trying to pass related params into a model with multiselect list. I need to assing classes to lecturers by choosing a lector when creating new class entry. I checked the db and got nothing in lecturers_id column. This is my form:
<%= f.select(:lecturers_id, Lecturer.all.collect {|l| [ l.name, l.id ] }, {}, { :multiple => true }) %>
My controller:
def subject_params
params.require(:subject).permit(:name, :credit, :number_of_hours, :lecturers_id => [])
end
def create
#subject = Subject.new(subject_params)
#subject.save
redirect_to "/subjects" and return
end
And my view:
<% #lecturers.each do |lect| %>
<tr>
<td class='col-md-3'><%= lect.name %></td>
<td class='col-md-3'>
<% lect.subjects do |subj| %>
<%= subj.name %>
<% end %>
</td>
<% end %>

Assuming the association is that Subject has_many :lecturers then you would change lecturers_id to lecturers_ids:
def subject_params
params.require(:subject).permit(:name, :credit, :number_of_hours, :lecturers_ids => [])
end
Form:
<%= f.select(:lecturers_ids, ...

In case of Subject has_many :lecturers. Your form should be
<%= f.select(:lecturer_ids, Lecturer.all.collect {|l| [ l.name, l.id ] }, {}, { :multiple => true }) %>
and your subject_params should be
def subject_params
params.require(:subject).permit(:name, :credit, :number_of_hours, :lecturer_ids => [])
end

Related

Ruby on rails 4 using filterrific to filter based on checkbox

I am using filterrific gem in my rails app to filter the result, i have events to be filtered based on the options
my code is as follows
event.rb
filterrific :default_filter_params => { :sorted_by => 'created_at_desc' },
:available_filters => %w[
sorted_by
search_query
with_category_id
with_area
]
# default for will_paginate
self.per_page = 9
scope :with_category_id, lambda { |category_ids|
where(category_id: [*category_ids])
}
events_controller.rb
def index
#filterrific = initialize_filterrific(
Event,
params[:filterrific],
:select_options => {
sorted_by: Event.options_for_sorted_by,
with_category_id: Category.options_for_select
}
) or return
#events = #filterrific.find.paginate(page: params[:page], per_page: 6).where(is_job: false)
respond_to do |format|
format.html
format.js
end
end
index.html.erb
<%= form_for_filterrific #filterrific, :class => 'col s12' do |f| %>
<%= render_filterrific_spinner %>
<%= f.hidden_field :source , :value => 'event' %>
<div class="col s12 m3 ">
<div class="filter-container">
<li>
<%= f.select(
:with_category_id,
#filterrific.select_options[:with_category_id],
{ include_blank: ' Any ' },
class: 'select-filter'
) %>
<label>select category</label>
</li>
</div>
<%= link_to(
'Reset filters',
reset_filterrific_url,
) %>
</div>
<% end %>
<%= render(
partial: 'events/list',
) %>
index.js.erb
<% js = escape_javascript(
render(partial: 'events/list')
) %>
$("#filterrific_results").html("<%= js %>");
$('#filterrific_results').load(document.URL + ' #filterrific_results');
_list.html.erb
<div id="filterrific_results">
<% #events.each do |event| %>
<%= link_to event.name, company_event_path(event.company.id, event.id) %>
<% end %>
</div>
so what i am doing here is i filtered the events based on their category with a select box
but now i want to add the feature in the select box that the select box must contain the checkbox elements so that i can filter multiple category result, so that when i check on one category it will filter the result by that single category and when i click another category it will filter the result with that category and previous category checked
Would be a great help to fix this , Thankx in advance
you can use multiple: true, like this:
<%= f.select(
:with_category_id,
#filterrific.select_options[:with_category_id],
{ include_blank: ' Any ' },
{ multiple: true, class: 'select-filter'}
) %>

getting checkbox value in ruby on rails

I have a checkbox below in a view page:
<table>
<tr>
<td>
<% #user_profession.each do |p| %>
<% if !p.Designation.blank? and p.Private? == "1" %>
<%= check_box(:ChkBx_Profession, {:id => "ChkBx_Profession",:value => "Profession"},true) %>
<%= label(:lb_Profession, "Profession") %>
<% else %>
<%= check_box(:ChkBx_Profession,{:id => "ChkBx_Profession",:value => "Profession"}) %>
<%= label(:lb_Profession, "Profession") %>
<% end %>
<% end %>
</td>
</tr>
</table>
Below is my controller page
if params[:ChkBx_Profession] == "1"
#blah = params[:ChkBx_Profession]
#publicprofession = params[:ChkBx_Profession]
Profession.delete_all(:UserID => current_user.id)
if !params[:tf_designation].blank?
#desig = params[:tf_designation]
#comp = params[:tf_company]
#fromdesigcom = params[:tf_fromdesignation]
#todesigcom = params[:tf_todesignation]
#public_profession = #publicprofession
#Profession = Profession.new( :UserID => current_user.id, :Designation => #desig, :Company => #comp, :Job_From => #fromdesigcom, :Job_To => #todesigcom, :Private? => #publicprofession )
#Profession.save
end
end
and I want to get the checkbox value means if checkbox is checked it gets me 1 and if checkbox is unchecked it gets me 0 but its get like this {"{:id=>\"ChkBx_Profession\", :value=>\"Profession\"}"=>"1"}. Kindly help me waiting for your reply.
Thanks
The second attribute on an check_box is the :value attribute. Try putting empty double quotes between the chec_box name AND the options:
<%= check_box(:YourCheckName, "",{Your Options}) %>

Validation in form?

I am trying to do validation but didnot find the right way while uploading the excel
Code for view
<%= form_for :dump, :url=> import_csv_index_path, :html => { :multipart => true } do |f| %>
<% if (-----).errors.any? %>
<div id="error_explanation">
<%= pluralize((----).errors.count, "error") %> prohibited this link from being saved:
<% (---).errors.full_messages.each do |msg| %>
<li><%= msg %></li>
</div>
<% end %>
<%= f.label :'Select an Excel File:' %>
<%= f.file_field :file %>
<i href="#" id="blob_1" class="icon-info-sign" rel="popover" style="margin-top: 300px"></i><br/>
<%= submit_tag 'Submit' ,:id => 'submit',:class =>"btn btn-primary"%><br/><br/>
<% end -%>
Code for model:
class Person < ActiveRecord::Base
attr_accessible :date, :email, :name, :avatar ,:template_id
validates_presence_of :email,:message => 'Email is compulsory'
end
What do i write at place of (-----)
Thank you
I have done with the other approach so discuss here,
Code for controller:
def import
#error = []
#error = Person.import(params[:dump][:file])
redirect_to people_path, notice: "Employees imported.",:flash => { :error => "Employees( Email : invalid/blank) are not saved : #{#error.join(" , ")}" }
end
In model:
def self.import(file)
spreadsheet = open_spreadsheet(file)
#err = []
#alt = []
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
#person = Person.find_by_id(row["id"]) ||Person.new
#person.name = row["Name"].to_s
#person.date = row["Date"]
#person.email = row["Email"]
if #person.save
else
#err << {:name => row["Name"].to_s,:error => #person.errors.messages}
end
end
#err.each do |t|
#alt.push(t[:name])
end
return #alt
end
and call that as flash message...and working fine now.
Thanks
I think somewhere in your controller you have to call .validate on a new instance of your Person model with your form's data. You can save that model in an instance variable that you can put in place of the (-----).

Sorting nested form fields in rails

I'm trying to create an inventory form that sorts the products based on their category. Ideally I'll be able to have these products listed by category, and will put in some javascript to hide/show products of a given category.
Currently, I'm having trouble wrapping my head around how to split my products up by category in my form. Here's what I currently have (modeled after Ryan Bates' Railscasts for nested attributes):
class InventoriesController < ApplicationController
def new
#title = "Take Inventory"
#vendor = ProductVendor.find(params[:product_vendor_id])
#inventory = Inventory.new()
#products = #vendor.products.active
#products.each do |product|
#inventory_line_item = #inventory.inventory_line_items.build({:product_id => product.id})
end
end
My form for a new inventory:
<%= form_for #inventory do |f| %>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
</tr>
<% f.fields_for :inventory_line_items do |builder| %>
<tr>
<td><%= builder.object.product.name %></td>
<td><%= builder.text_field(:quantity, :size => 3) %></td>
<%= builder.hidden_field :product_id %>
</tr>
<% end %>
</table>
<%= f.hidden_field(:user_id, :value => current_user.id) %>
<%= f.hidden_field(:location_id, :value => current_location.id) %>
<%= f.hidden_field(:product_vendor_id, :value => #vendor.id) %>
<%= f.submit "Submit" %>
<% end %>
So I have another model called product_category that has_many products. How do I sort and separate my products by category in the controller and form? Also, is there a way to do this using Formtastic? Thanks!
It's actually pretty simple to implement. Add a hidden field in the nest_form field with the attribute position (add this attr to your model of course) and add this to your js along with using the jquery-ui.js
$('#task_fields').sortable({
items: '.fields',
dropOnEmpty: true,
cursor: 'move',
handle: '.move',
opacity: 0.4,
scroll: true,
axis:'y',
placeholder: 'ui-state-highlight',
start: function(e, ui) {
ui.placeholder.height(ui.item.height());
},
update: function() {
$(this).children(".fields").each(function(index) {
$(this).children('input.task_position').val(index + 1);
});
}
});
here's what I have in my _form.html.haml
= f.fields_for :tasks do |t|
= t.text_field :name
= t.hidden_field :position, :class => :task_position
= t.collection_select :account_id, Account.all, :id, :full_name, :prompt => 'Assign task to...'
.button-group
%span{:class => "button icon no-text move pill"}
= t.link_to_remove "", :class => "button icon no-text remove pill"
= f.link_to_add "Add a Task", :tasks, :class => "button icon add"
This worked really well.

Rails custom validations with multi-model forms

I'm having problems with my rails custom validations.
def validates_hsp_program(*attr_names)
options = attr_names.extract_options!
regex = '^('
err = ''
$CetConfig.program.each do |key, val|
regex << val.to_s << '|'
err << $CetConfig.program_prefix + " " + val.to_s + ", "
end
regex.chomp!('|')
regex << ')$'
regex = Regexp.new(regex)
validates_each attr_names do | record, attr_name, value |
exit 1
unless value.nil? or value =~ regex
record.errors.add(attr_name, 'must be one of ' + err.chomp(", "));
end
end
end
The problem is that for debugging purposes I added exit 1 as I wasn't getting the error message for invalid date for that field. However, it never exits. This is the same thing I do in all my other custom validators. The only difference I can see is that this one is the second model of a multi-model form and all the others are on the first model... What am I doing wrong?
My Model
class ProfileProgram < ActiveRecord::Base
set_table_name "profile_program"
set_primary_key "STUDENT_ID"
belongs_to :profile_core, :primary_key => "STUDENT_ID", :foreign_key => "STUDENT_ID"
validates_presence_of :program
validates_hsp_program :program
end
Action from my controller
def create
#pc = ProfileCore.new(params[:profile_core])
#pp = ProfileProgram.new(params[:profile_program])
#pc.student_type = $CetConfig.student_type.application
#pc.AGENT_ID = current_agents_staff.AGENT_ID
year = #pc.contract.to_s
case #pp.program
when 10 then
sd = year + '-09-01'
ed = year + '-06-30'
when 51 then
sd = year + '-08-15'
ed = year + '-06-30'
when 52 then
sd = year + '-01-15'
ed = year + '-06-30'
when 12 then
sd = year + '-01-15'
ed = year + '-01-14'
else
sd = nil
ed = nil
end
#pc.start_date = Date.parse(sd) unless sd.nil?
#pc.end_date = Date.parse(ed) unless ed.nil?
#pc.program_status = $CetConfig.student_status.apply
if #pc.valid? and #pp.valid?
ProfileCore.transaction do
#pc.save!
#pp.save!
end
redirect_to(students_path(#pc.STUDENT_ID))
else
render :action => 'new'
end
end
My view (element_block is a helper that just stuffs the label and field into the right tags for the dl)
<% form_for :profile_core, #pc, :url => { :controller => 'core', :action => 'create'} do |f| %>
<%= error_messages_for :object => [ #pc, #pp ] %>
<dl>
<%= element_block f.label(:contract, 'Contract Year'), f.contract_year_select(:contract) %>
<% fields_for :profile_program do |pp| %>
<%= element_block pp.label(:program, 'Program'), pp.hsp_program_select(:program) %>
<% end %>
<%= element_block f.label(:passport_number, 'Passport Number'), f.text_field(:passport_number) %>
<%= element_block f.label(:passport_country, "Country that issued the student's passport"), f.countries_select(:passport_country) %>
<%= element_block f.label(:passport_expires, 'Passport Expiration Date'), f.text_field(:passport_expires, :class => 'datepicker') %>
<%= element_block f.label(:last_name, 'Last Name (as on passport)'), f.text_field(:last_name) %>
<%= element_block f.label(:first_name, 'First Name (as on passport)'), f.text_field(:first_name) %>
<%= element_block f.label(:middle_name, 'Middle Name (as on passport)'), f.text_field(:middle_name) %>
<%= element_block f.label(:other_names, 'Other Names'), f.text_field(:other_names) %>
<%= element_block f.label(:residence_street_address, 'Street Address'), f.text_field(:residence_street_address) %>
<%= element_block f.label(:residence_city, 'City'), f.text_field(:residence_city) %>
<%= element_block f.label(:residence_province, 'Province'), f.text_field(:residence_province) %>
<%= element_block f.label(:residence, 'Country'), f.text_field(:residence) %>
<%= element_block f.label(:residence_postal_code, 'Postal Code'), f.text_field(:residence_postal_code) %>
<%= element_block f.label(:birthdate, 'Date of Birth'), f.text_field(:birthdate, :class => 'datepicker', :id => "student_birth_date") %>
<%= element_block f.label(:citizenship, 'Country of Citizenship'), f.countries_select(:citizenship) %>
<%= element_block f.label(:birth_city, 'Birth City'), f.text_field(:birth_city) %>
<%= element_block f.label(:nationality, 'Nationality'), f.countries_select(:nationality) %>
<%= element_block f.label(:gender, 'Gender'), f.gender_select(:gender) %>
<%= element_block f.label(:email, 'Email'), f.text_field(:email) %>
<%= element_block f.label(:desires_esl, 'Does the student wish to participate in CLEP?'), f.bool_yes_no_select(:desires_esl) %>
<%= element_block f.label(:may_pay_tuiton, 'Willing to pay tuition'), f.yes_no_select(:may_pay_tuition) %>
</dl>
<div class="submit"><%= submit_tag("Proceed to Step Two") %></div>
<% end %>
This is how I ended up taking care of it with accepts_nested_attributes_for
Primary Model. (Irrelevant code replaced with ellipses)
class ProfileCore < ActiveRecord::Base
set_table_name "profile_core"
set_primary_key "STUDENT_ID"
belongs_to :agents_profile, :primary_key => "AGENT_ID", :foreign_key => "AGENT_ID"
has_one :profile_program, :primary_key => "STUDENT_ID", :foreign_key => "STUDENT_ID"
accepts_nested_attributes_for :profile_program
...
end
Secondary Model
class ProfileProgram < ActiveRecord::Base
set_table_name "profile_program"
set_primary_key "STUDENT_ID"
belongs_to :profile_core, :primary_key => "STUDENT_ID", :foreign_key => "STUDENT_ID"
validates_presence_of :program
validates_hsp_program :program
end
New action in the controller. (Create was irrelevant)
def new
#pc = ProfileCore.new
#pp = #pc.build_profile_program
end
View
<% form_for #pc, :url => { :controller => 'core', :action => 'create'} do |f| %>
<%= f.error_messages %>
<dl>
<%= element_block f.label(:contract, 'Contract Year'), f.contract_year_select(:contract) %>
<% f.fields_for :profile_program do |pp| %>
<%= element_block pp.label(:program, 'Program'), pp.hsp_program_select(:program) %>
<% end %>
<%= element_block f.label(:passport_number, 'Passport Number'), f.text_field(:passport_number) %>
...
<% end %>
It's not correct custom validation implementation, try something like that:
http://marklunds.com/articles/one/312
or http://chrisblunt.com/blog/2009/04/18/rails-writing-dry-custom-validators/

Resources