Rails, How i can create grouped_select? - ruby-on-rails

I'm new in rails and i need a help.
I wanna to do a grouped selection on rails but i dont know how i can do it.
i have 3 db tables cars, car_brands and car_models. When i add new car i need to select car model, how i can do it with gtouped selection.
models/car_brand.rb
class CarBrand < ActiveRecord::Base
has_many :cars
has_many :car_models
mount_uploader :logo, CarBrandImgUploader
end
models/car_model.rb
class CarModel < ActiveRecord::Base
has_many :cars
belongs_to :car_brand
end
cars_controller.rb
class CarsController < ApplicationController
before_action :set_car, only: [:show, :edit, :update, :destroy]
before_action :set_model, only: [:index, :new, :edit]
# GET /cars
# GET /cars.json
def index
#cars = Car.all
end
# GET /cars/1
# GET /cars/1.json
def show
end
# GET /cars/new
def new
#car = Car.new
end
# GET /cars/1/edit
def edit
end
# POST /cars
# POST /cars.json
def create
#car = Car.new(car_params)
respond_to do |format|
if #car.save
if params[:ImagesCars]
params[:ImagesCars]['image'].each do |a|
#ImagesCar = #car.ImagesCars.create!(:image => a, :car_id => #car.id)
end
end
format.html { redirect_to #car, notice: 'Car was successfully created.' }
format.json { render :show, status: :created, location: #car }
else
format.html { render :new }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /cars/1
# PATCH/PUT /cars/1.json
def update
respond_to do |format|
if #car.update(car_params)
if params[:ImagesCars]
params[:ImagesCars]['image'].each do |a|
#ImagesCar = #car.ImagesCars.create!(:image => a, :car_id => #car.id)
end
end
format.html { redirect_to #car, notice: 'Car was successfully updated.' }
format.json { render :show, status: :ok, location: #car }
else
format.html { render :edit }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
end
end
# DELETE /cars/1
# DELETE /cars/1.json
def destroy
#car.destroy
respond_to do |format|
format.html { redirect_to cars_url, notice: 'Car was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_car
#car = Car.find(params[:id])
end
def set_model
#models = CarModel.all
#brands = CarBrand.all
end
# Never trust parameters from the scary internet, only allow the white list through.
def car_params
params.require(:car).permit(:title_en, :keys_en, :description_en, :text_en, :title_fr, :keys_fr, :description_fr, :text_fr, :title_ru, :keys_ru, :description_ru, :text_ru, :title_es, :keys_es, :description_es, :text_es, :model_id, :brand_id, :price_day, :price_week, :p_info, :images_cars => [:id, :car_id, :image])
end
end
cars/new.html.haml
= simple_form_for(#car, html: { role: 'form', multipart: true }) do |f|
= f.input :price_day, as: :integer, input_html: {class: 'form-control', placeholder: 'Price Day ej: 150'}
= f.cktext_area :text_en, as: :text, input_html: { class: 'form-control' }, :label => 'EN Website Content Text EN'
=f.input :model_id, collection: #models, as: :grouped_select, group_method: :brand_id
= f.submit 'Save'
i get this error:
undefined method `map' for nil:NilClass
Please help or explain how i can do the grouped selection.
Thx

Related

rails strong parameters not work correctly

i have a rails app. i have strange problem in saving form
this is my ticket model .
class Ticket < ApplicationRecord
belongs_to :user
has_many :ticketissues , inverse_of: :ticket
accepts_nested_attributes_for :ticketissues, :reject_if => lambda { |a| a[:body].blank? }
end
this is ticketisue model
class Ticketissue < ApplicationRecord
belongs_to :user
belongs_to :ticket
validates :body, presence: true
end
this is ticket controller
class TicketsController < ApplicationController
before_action :set_ticket, only: [:show, :edit, :update, :destroy]
# GET /tickets
# GET /tickets.json
def index
#tickets = Ticket.all
end
# GET /tickets/1
# GET /tickets/1.json
def show
end
# GET /tickets/new
def new
#ticket = Ticket.new
end
# GET /tickets/1/edit
def edit
end
# POST /tickets
# POST /tickets.json
def create
#ticket = Ticket.new(ticket_params)
#ticket.user_id = current_user.id
#ticket.ticketissues.build
respond_to do |format|
if #ticket.save
format.html { redirect_to #ticket, notice: 'Ticket was successfully created.' }
format.json { render :show, status: :created, location: #ticket }
else
format.html { render :new }
format.json { render json: #ticket.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tickets/1
# PATCH/PUT /tickets/1.json
def update
respond_to do |format|
if #ticket.update(ticket_params)
format.html { redirect_to #ticket, notice: 'Ticket was successfully updated.' }
format.json { render :show, status: :ok, location: #ticket }
else
format.html { render :edit }
format.json { render json: #ticket.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tickets/1
# DELETE /tickets/1.json
def destroy
#ticket.destroy
respond_to do |format|
format.html { redirect_to tickets_url, notice: 'Ticket was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ticket
#ticket = Ticket.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def ticket_params
params.require(:ticket).permit(:subject, :subsubject, :user_id, ticketissues_attributes: [
:body, :id, :_destroy] )
#params.require(:ticket).permit!
end
end
and my view is like this
<%= f.input :subject , collection: [ "تغییر اطلاعات کسب و کار",
"تغییر اطلاعات یک کوپن",
"سایر موارد"] %>
<%= f.input :subsubject %>
<!-- <%= f.association :user %> -->
</div>
<%= f.simple_fields_for :ticketissue do |p| %>
<%= p.input :body %>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
but when i want to create a ticket , form will not save to database
and i get this error:
Started POST "/tickets" for 127.0.0.1 at 2017-04-11 23:52:33 +0430
Processing by TicketsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fsl6nTe0PjmBKpeuh16BRFlYOw0MB93LEYDVEAl6TtT/uu/LwGTA0P2q0bRxIxBUqHqZINXHntrZLt7MuCG84Q==", "ticket"=>{"subject"=>"تغییر اطلاعات کسب و کار", "subsubject"=>"lk", "ticketissue"=>{"body"=>"lkjkjkjkjkkjkj"}}, "commit"=>"Create Ticket"}
Unpermitted parameter: ticketissue
but when i use console and this command:
Ticket.create(subject: 'test' , subsubject: 'ticket test' , ticketissues_attributes: [{body: "[some thing" }] )
every things work fines and all data save.
tanks for read and help.
You must use the plural here
= f.simple_fields_for :ticketissues do |p|

How preview multiple images with nested form rails

I'm using paperclip to upload images and nested form.
I want to preview images as input, not just an image.
This is my form.
= nested_form_for #anime, html:{multipart:true} do |f|
- if #anime.errors.any?
#error_explanation
%h2= "#{pluralize(#anime.errors.count, "error")} prohibited this anime from being saved:"
%ul
- #anime.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_area :name
.fields
=f.fields_for :images do |i|
=i.file_field :content
=i.link_to_remove "Remove"
.field
=f.link_to_add "add Image", :images
.actions
= f.submit 'Save'
This is my model.
class Image < ApplicationRecord
belongs_to :imageable, :polymorphic => true, optional:true
has_attached_file :content, :styles=>{:medium => "300x300>", :thumb => "100x100>"}
validates_attachment_content_type :content, :content_type => %w(image/jpeg image/jpg image/png)
end
class Anime < ApplicationRecord
has_many :images, :as => :imageable, dependent: :destroy
accepts_nested_attributes_for :images, :allow_destroy => true
end
This is my controller
class AnimesController < ApplicationController
before_action :set_anime, only: [:show, :edit, :update, :destroy]
# GET /animes
# GET /animes.json
def index
#animes = Anime.all
end
# GET /animes/1
# GET /animes/1.json
def show
end
# GET /animes/new
def new
#anime = Anime.new
#anime.images.build
end
# GET /animes/1/edit
def edit
end
# POST /animes
# POST /animes.json
def create
#anime = Anime.new(anime_params)
respond_to do |format|
if #anime.save
format.html { redirect_to #anime, notice: 'Anime was successfully created.' }
format.json { render :show, status: :created, location: #anime }
else
format.html { render :new }
format.json { render json: #anime.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /animes/1
# PATCH/PUT /animes/1.json
def update
respond_to do |format|
if #anime.update(anime_params)
format.html { redirect_to #anime, notice: 'Anime was successfully updated.' }
format.json { render :show, status: :ok, location: #anime }
else
format.html { render :edit }
format.json { render json: #anime.errors, status: :unprocessable_entity }
end
end
end
# DELETE /animes/1
# DELETE /animes/1.json
def destroy
#anime.destroy
respond_to do |format|
format.html { redirect_to animes_url, notice: 'Anime was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_anime
#anime = Anime.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def anime_params
params.require(:anime).permit(:name, images_attributes: [:content])
end
end
Please help me
Thanks so much.
ignore this message

How to save associated id in Rails?

batchnotification_controller.rb
class BatchNotificationsController < ApplicationController
before_action :set_batch_notification, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#batch_notification = BatchNotification.new
#users = User.all
#batch_notifications = BatchNotification.all
#final_count = []
#calculated_batch_counts = CalculatedBatchCount.all.group_by{|x| x.batch.batch_number if !x.batch.nil? }
#a = CalculatedBatchCount.all.group_by{|k| k.batch.serial_id if !k.batch.nil? }
#calculated_batch_counts.each do |key, values|
count = values.map{|x| x.finalCount}.length
h = {"batch_number" => key, "batch_id" => values.map{|x| x.batch.serial_id},"finalcount" => values.map{|x| x.finalCount}.sum(:+)/count}
#final_count << h
end
puts
# => render :json => #final_count and return
respond_with(#batch_notifications)
end
def show
respond_with(#batch_notification)
end
def new
#batch_notification = BatchNotification.new
respond_with(#batch_notification)
end
def edit
end
def create
#batch_notification = BatchNotification.new(batch_notification_params)
respond_to do |format|
if #batch_notification.save
format.html { redirect_to batch_notifications_path, notice: 'batch_notification was successfully created.' }
format.json { render action: 'index', status: :created, location: #batch_notification }
format.js
else
format.js
format.html { render action: 'new' }
format.json { render json: #batch_notification.errors, status: :unprocessable_entity }
end
end
end
def update
#batch_notification.update(batch_notification_params)
respond_to do |format|
if #vehicle.update(vehicle_params)
format.html { redirect_to #batch_notification, notice: 'batch_notification was successfully updated.' }
format.json { head :no_content }
format.js
else
format.js
format.html { render action: 'edit' }
format.json { render json: #batch_notification.errors, status: :unprocessable_entity }
end
end
end
def destroy
#batch_notification.destroy
respond_with(#batch_notification)
end
private
def set_batch_notification
#batch_notification = BatchNotification.find(params[:id])
end
def batch_notification_params
params.require(:batch_notification).permit(:message,:approved,:finalCount, :batch_id, :user_id)
end
end
user_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
load_and_authorize_resource
# GET /users
# GET /users.json
def index
#users = User.all.order('created_at DESC')
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
respond_to do |format|
if #user.save
format.html { redirect_to users_path, notice: 'User was successfully created.' }
format.json { render action: 'show', status: :created, location: #user }
format.js
else
# render :text => #user.errors.inspect and return
format.html { redirect_to users_path, notice: 'Erors while creating User'}
format.json { render json: #user.errors, status: :unprocessable_entity }
format.js
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
# def update
# respond_to do |format|
# if #user.update(user_params)
# format.html { redirect_to #user, notice: 'User was successfully updated.' }
# format.json { head :no_content }
# else
# format.html { render action: 'edit' }
# format.json { render json: #user.errors, status: :unprocessable_entity }
# end
# end
# end
def update
if user_params[:password].blank?
user_params.delete(:password)
user_params.delete(:password_confirmation)
end
params[:user][:name] = params[:user][:name].capitalize if !params[:user][:name].nil?
successfully_updated = if needs_password?(#user, user_params)
#user.update(user_params)
else
#user.update_without_password(user_params)
end
respond_to do |format|
if successfully_updated
format.html { redirect_to users_path, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
format.js { render :layout => false}
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :name, :role_id,:department_id,:encrypted_password, :plant_id)
end
protected
def needs_password?(user, params)
params[:password].present?
end
end
batchnotification.rb
class BatchNotification
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Autoinc
field :finalCount, type: Float
field :message, type: String
field :approved, type: Boolean
field :batch_id, type: Integer
field :user_id, type:Integer
belongs_to :batch
belongs_to :user
belongs_to :calculated_batch_counts
end
user.rb
class User
include Mongoid::Document
include Mongoid::Timestamps
include DeviseTokenAuth::Concerns::User
# field :locked_at, type: Time
field :name, type: String
field :role_id , type: Integer
field :department_id , type: Integer
## unique oauth id
field :provider, type: String
field :uid, default: ""
belongs_to :role
belongs_to :department
belongs_to :plant
has_and_belongs_to_many :batches, :dependent => :destroy
has_many :batch_notifiations , :dependent => :destroy
end
_form.html.erb
<%= simple_form_for(#batch_notification) do |f| %>
<%= f.error_notification %>
<%= f.check_box :approved, label: false%>
<%= f.input :message, label: false, placeholder:"message"%>
<%= f.submit "Add", class: "btn btn-primary" %>
<% end %>
I have two models with belongs to, has_many associations. Here not saving User_id in Batchnotification model please tell me the detailed procedure to how to store user id.

Edit model in has_many through relation

I want to edit a has_many through relation, but instead of editing the relation, it creates a new model.
In my form:
<%= form_for #service do |f| %>
<%= f.fields_for :service_users do |ac| %>
<% end %>
<% end %>
In my model:
class Service < ActiveRecord::Base
has_many :service_users
has_many :users, :through => :service_users
accepts_nested_attributes_for :service_users
end
Begin situation:
When i update the comments field:
After updating i see the edited relation as a duplication of the first one.
In some way i have to check if there're already relations present, but how?
Update:
My controller:
class ServicesController < ApplicationController
before_action :set_service, only: [:show, :edit, :update, :destroy, :users]
before_filter :authenticate_user!
# GET /services
# GET /services.json
def index
services = current_user.available_services
#available_services = services.group_by { |t| t.date.beginning_of_month }
end
# GET /services/1
# GET /services/1.json
def show
# service_users = current_user.service_users
#
# Service.find_each do |service|
# unless service_users.detect { |m| m.service_id == service.id }
# current_user.service_users.build service_id: service.id
# end
# end
#
#available_users = #service.available_users.group_by { |u| u.group }
#planned_users = #service.planned_users.group_by { |u| u.group }
#reserve_users = #service.reserve_users.group_by { |u| u.group }
end
# GET /services/new
def new
#service = Service.new
end
# GET /services/1/edit
def edit
#service.service_users.create
end
# POST /services
# POST /services.json
def create
#service = Service.new(service_params)
p service_params
respond_to do |format|
if #service.save
format.html { redirect_to #service, notice: 'Service was successfully created.' }
format.json { render action: 'show', status: :created, location: #service }
else
format.html { render action: 'new' }
format.json { render json: #service.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /services/1
# PATCH/PUT /services/1.json
def update
respond_to do |format|
p service_params[:service_users_attributes]
if #service.update(service_params)
format.html { redirect_to #service, notice: 'Service was successfully updated.' }
format.json { render action: 'show', status: :ok, location: #service }
else
format.html { render action: 'edit' }
format.json { render json: #service.errors, status: :unprocessable_entity }
end
end
end
def users
#users = #service.users
end
# DELETE /services/1
# DELETE /services/1.json
def destroy
#service.destroy
respond_to do |format|
format.html { redirect_to services_url }
format.json { head :no_content }
end
end
def destroy_association
if params[:id].present?
ServiceUser.find(params[:id]).delete
redirect_to root_path
end
end
def make_user_available_for_service
p '########'
p params
p #service
redirect_to root_path
end
private
# Use callbacks to share common setup or constraints between actions.
def set_service
#service = Service.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def service_params
params.require(:service).permit(:date, :comments,
service_users_attributes: [:user_id,
:service_id,
:availability,
:comments],
service_groups_attributes: [:service_id,
:group_id,
:start_time,
:end_time])
end
end
Try build instead of create.
Like this:
def edit
#service.service_users.build
end
And check your service_params.
Your missing an id for the service_users.

accepts_nested_attributes_for not working properly

I'm fairly new to rails, building my first app. I'm running rails 4 w/ bootstrap 3. I'm trying to get a complex form to work. I have two models:
class Employee < ActiveRecord::Base
belongs_to :company
belongs_to :user, :through => :company
has_one :position
accepts_nested_attributes_for :position
end
class Position < ActiveRecord::Base
belongs_to :employees
accepts_nested_attributes_for :employees
end
I have a form where the User can create a new job title (Position Model) and select the employees (Employees Model) that position will be applied to. Basically it's a single form that will add fields to 2 different database tables (Position and Employee).
This is my view:
<%= simple_form_for(#position) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :job_title %>
<%= f.input :job_description %>
</div>
<%= f.fields_for :Employee do |f| %>
<%= f.input :employee_title, label: "Apply to:", collection: Employee.all, label_method: :first_name, as: :check_boxes %>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Below are the controllers:
class PositionsController < ApplicationController
before_action :set_position, only: [:show, :edit, :update, :destroy]
# GET /positions
# GET /positions.json
def index
#positions = Position.all
end
# GET /positions/1
# GET /positions/1.json
def show
end
# GET /positions/new
def new
#position = Position.new
end
# GET /positions/1/edit
def edit
end
# POST /positions
# POST /positions.json
def create
#position = Position.new(position_params)
respond_to do |format|
if #position.save
format.html { redirect_to #position, notice: 'position was successfully created.' }
format.json { render action: 'show', status: :created, location: #position }
else
format.html { render action: 'new' }
format.json { render json: #position.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /positions/1
# PATCH/PUT /positions/1.json
def update
respond_to do |format|
if #position.update(position_params)
format.html { redirect_to #position, notice: 'position was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #position.errors, status: :unprocessable_entity }
end
end
end
# DELETE /positions/1
# DELETE /positions/1.json
def destroy
#position.destroy
respond_to do |format|
format.html { redirect_to positions_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_position
#position = Position.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def position_params
params.require(:position).permit(:position_title, :position_description, :position_create_date)
end
end
class EmployeesController < ApplicationController
# encoding: UTF-8
before_action :set_employee, only: [:show, :edit, :update, :destroy]
# GET /employees
# GET /employees.json
def index
#employees = Employee.all
end
# GET /employees/1
# GET /employees/1.json
def show
end
# GET /employees/new
def new
#employee = Employee.new
end
# GET /employees/1/edit
def edit
end
# POST /employees
# POST /employees.json
def create
#employee = Employee.new(employee_params)
respond_to do |format|
if #employee.save
format.html { redirect_to #employee, notice: 'Employee was successfully created.' }
format.json { render action: 'show', status: :created, location: #employee }
else
format.html { render action: 'new' }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /employees/1
# PATCH/PUT /employees/1.json
def update
respond_to do |format|
if #employee.update(employee_params)
format.html { redirect_to #employee, notice: 'Employee was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
# DELETE /employees/1
# DELETE /employees/1.json
def destroy
#employee.destroy
respond_to do |format|
format.html { redirect_to employees_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_employee
#employee = Employee.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def employee_params
params.require(:employee).permit(:first_name, :last_name, :employee_title)
end
end
The problem I'm facing is I get the form to render perfectly, but when I submit it, only fields that belong to the Position model get recorded. The :employee_title stays blank. Any suggestions what the problem is?
Thank you!!
Too many points to fit in a comment:
belongs_to :employees should be singular: belongs_to :employee
Your fields_for should be like (differentiate the ff from parent form):
<%= f.fields_for :Employee do |ff| %>
<%= ff.input :employee_title, label: "Apply to:", collection: Employee.all,
label_method: :first_name, as: :check_boxes %>
<% end %>
If it doesn't work, supply your controller also and I'll update my answer.
Edit:
After seeing your controllers, it seems most likely to be case of unpermitted params.
In position_controller.rb add employee params to position params
def position_params
params.require(:position).permit(:position_title, :position_description, :position_create_date, employees_attributes: [:first_name, :last_name, :employee_title])
end

Resources