How to save associated id in Rails? - ruby-on-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.

Related

Proper way of displaying an error from controller when the error is in relationship

My project model has a many to many relationship to Users (members). I have an invitation form that allows users to enter an email to add members to a project. If the user enters an invalid email address or an email that doesn't correlate to a User in the database, no error is displayed. I would like to provide an error message. What is the best way of accomplishing this?
I created the invite method on the Project model and only running it if the #user exists in the invitation controller. I would like to provide an error message that the member wasn't added because the User doesn't exist.
Invitation Form
<%= form_with(url: "/projects/#{#project.id}/invitation", method: "post") do %>
<div class="mb-3">
<%= text_field_tag :email, nil, class: "border border-gray rounded w-ful py-2 px-3", placeholder: "Email Address", autofocus: true %>
</div>
<%= submit_tag("Invite", class: 'button') %>
<% end %>
Invitation Controller
module Projects
class InvitationController < ApplicationController
before_action :set_user
# POST /projects/{id}/invitation
# POST /projects/{id}/invitation.json
def create
#project = Project.find(params[:project_id])
if #user
#project.invite(#user)
end
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: "User was successfully added." }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
private
def set_user
#user = User.with_email(params[:email]).first
end
end
end
Project Model
class Project < ApplicationRecord
include ActivityRecorder
belongs_to :user
has_many :tasks
has_many :activities, -> { order(created_at: :desc) }
has_many :subjects, -> { order(created_at: :desc) }, as: 'subject'
has_and_belongs_to_many :members,
class_name: 'User',
join_table: "members_projects",
foreign_key: "projects_id",
association_foreign_key: "users_id"
validates_presence_of :title, :description, :user
def invite(user)
self.members << user unless self.members.include?(user)
end
end
User Model
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :projects
has_and_belongs_to_many :projects_as_member,
class_name: 'Project',
join_table: "members_projects",
foreign_key: "users_id",
association_foreign_key: "projects_id"
scope :with_email, ->(email) { where("email = ?", email) }
def get_md5_email
Digest::MD5.hexdigest(self.email)
end
end
Projects Controller
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
before_action :require_user
before_action :verify_project_access, only: [:show]
# GET /projects
# GET /projects.json
def index
#projects = Project.where(user: current_user).or(Project.where(id: current_user)).order('updated_at DESC')
end
# GET /projects/1
# GET /projects/1.json
def show
#task = Task.new
end
# GET /projects/new
def new
#project = Project.new
end
# GET /projects/1/edit
def edit
end
# POST /projects
# POST /projects.json
def create
#project = Project.new(project_params)
#project.user = current_user
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: "Project was successfully created." }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: "Project was successfully updated." }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: "Project was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find(params[:id])
end
# Only allow a list of trusted parameters through.
def project_params
params.require(:project).permit(:title, :description, :notes)
end
def verify_project_access
if #project.user != current_user
flash[:danger] = "You don't have access this project"
redirect_to projects_url
end
end
end
I was hoping for a better way to do this but I ended up just simply:
if #user
#project.invite(#user)
else
redirect_to #project, alert: "Invalid user was entered"
return
end
Invitation Controller
module Projects
class InvitationController < ApplicationController
before_action :set_user
# POST /projects/{id}/invitation
# POST /projects/{id}/invitation.json
def create
#project = Project.find(params[:project_id])
if #user
#project.invite(#user)
else
redirect_to #project, alert: "Invalid user was entered"
return
end
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: "User was successfully added." }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
private
def set_user
#user = User.with_email(params[:email]).first
end
end
end

Rails form not redirecting to Show action

I have three models City, Area and User
In new user form after clicking on submit button server/app is not redirecting to show action
(my routes file config/routes)
Rails.application.routes.draw do
resources :areas
resources :cities
get 'users/update_cities'
resources :users
(user controller app/controllers/users_controller.rb )
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
def update_cities
#areas = Area.where("city_id = ?", params[:city_id])
respond_to do |format|
format.js
end
end
# GET /users
# GET /users.json
def index
#users = User.all
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
#cities = City.all
#areas = Area.where("city_id = ?", City.first.id)
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
#user.area_ids = [params[:user][:area_id]]
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
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 { render :show, status: :ok, location: #user }
else
format.html { render :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, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
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(:name, :brief,:area_id)
end
end
and form (app/views/users/_form.html.erb)
(labels not included just to clean up d code a bit )
<%= form_for(#user, remote: true) do |f| %>
<%= f.text_field :name %>
<%= f.select :city_id, options_for_select(#cities.collect { |city|
[city.name.titleize, city.id] }), {include_blank: 'Select Something'}, { id: 'cities_select'} %>
<%= f.select :area_id, options_for_select(#areas.collect { |area|
[area.name.titleize, area.id] }, 0), {}, { id: 'areas_select' } %>
<%= f.submit %>
please help.. !
The remote: true parameter in your form is causing the problem. This setting is useful when you want to update/create an object, without updating the view you're in.
For more information you can check ruby on rails API

Rails, How i can create grouped_select?

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

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.

Can't Mass assign attributes with nested form

I have 2 forms, a orders form and a products form. I would like the products form to be under the orders form. I am getting this error: Can't mass-assign protected attributes: products_attributes.
Here is my orders model
class Order < ActiveRecord::Base
attr_accessible :comments, :due_date, :order_type, :print_color, :print_location, :title,
:products
validates :order_type, :due_date, :print_color, :title, :presence => true
validates :title, :uniqueness => true
has_many :products
accepts_nested_attributes_for :products, :allow_destroy => true
end
products model
class Product < ActiveRecord::Base
attr_accessible :quantity
has_one :order
end
orders controller:
>class OrdersController < ApplicationController
# GET /orders
# GET /orders.json
def index
#orders = Order.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #orders }
end
end
# GET /orders/1
# GET /orders/1.json
def show
#order = Order.find(params[:id])
#products = #order.products.find(:all)
respond_to do |format|
format.html # show.html.erb
format.json { render json: #order }
end
end
# GET /orders/new
# GET /orders/new.json
def new
#order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #order }
end
end
# GET /orders/1/edit
def edit
#order = Order.find(params[:id])
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(params[:order])
respond_to do |format|
if #order.save
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render json: #order, status: :created, location: #order }
else
format.html { render action: "new" }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# PUT /orders/1
# PUT /orders/1.json
def update
#order = Order.find(params[:id])
respond_to do |format|
if #order.update_attributes(params[:order])
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order = Order.find(params[:id])
#order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :no_content }
end
end
end
any help would be appreciated! thanks in advance.
Replace:
attr_accessible ..., :products
With:
attr_accessible ..., :products_attributes

Resources