Request denied while updating user details in rails - ruby-on-rails

I'm new to ruby on rails.
I've two type of users Admin and User. Admin can create edit and destroy user. I've no problem with create and destroy and have implemented quite easily.
I've used following code in controller,
private
def allowed_params
params.require(:user).permit(:role_id, :email, :password, :password_confirmation, :fname, :lname)
end
to define parameters required and allowed while creating user.
User Create
def save_user
#user = User.new(allowed_params)
if #user.save
redirect_to list_users_path
else
render 'add_user'
end
end
User Update
def update_user
#user = User.find(params[:id])
if #user.update_attributes(allowed_params)
redirect_to list_users_path
else
render 'edit_user'
end
end
View
<div class="container">
<div class="row">
<div class="col-md-12">
<%= link_to "Admin Dashboard", admin_dashboard_path, :class=>'pull-left' %>
<%= form_for #user, :url => update_user_path do |f| %>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<h2 style="text-align: center;">Edit User Details</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :fname, 'First Name' %><br />
<%= f.text_field :fname, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :fname) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :lname, 'Last Name' %><br />
<%= f.text_field :lname, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :lname) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :email, 'Email' %><br />
<%= f.text_field :email, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :email) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3" style="text-align: center">
<%= f.submit "Update User", :class => 'btn btn-sm btn-primary' %>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
when I pass only fname, lname and email nothing happened. I need to update user details what should I do here ?
Any suggestion is appreciated.

There is a debug way.
You should launch the server in development mode. Then check the changes of development.log file in the terminal by tail -f log/development.log.
Then do what you want, such as click the "submit" button when you changed the fname or other fields.
Then focus on the informations got on step 1. There are what you can get:
A. which Controller and action handled the request
B. The parameters of this request.
C. The log of SQLs excuted by DB
D. The response status
Check if the right Controller? or right parameters? or SQLs has been excuted? In addition, we used to #user.update_attributes!(allowed_params) when debug. It take more informations when something disobeys the rules defined in Model(User).

Related

How to add in multiple options for checkbox in Ruby on Rails?

This is likely a super easy answer for a Ruby on Rails expert. I have a form and need to add in a checkbox that has multiple items. I've been messing with the following code for a lot longer than I'd like to admit:
<%= form_for :lead, url: something, html: {id: 'product-form'} do |f|%>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= f.label :product%>
<%= f.check_box :product, {multiple:true}, "option", "option2", :class => 'form-control'%>
</div>
</div>
</div>
<% end %>
With this code I get the error "wrong number of arguments (5 for 1..4)".
Basically I just want someone to be able to pick multiple options. I've also tried the following:
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= f.label :product%>
<%= f.check_box :option1, "Option1" :class => 'form-control'%>
<%= f.check_box :option2, "Option2", :class => 'form-control'%>
</div>
</div>
</div>
And I get the delightful "undefined method `merge' for "Option1":String". What am I missing to put the values in associated with the label?
I use Rails 5.1.6 and this is how I achieved adding multiple options for checkbox. I also placed it in a dropdown.
In the migration file:
t.string :skills
In my controller "tasks_controller.rb":
def task_params
params.require(:task).permit(:work_type, :title, :post, {skills: []})
end
In my model "task.rb" I did:
validates :skills, presence: true
serialize :skills, JSON
I created a module mobilephones_data.rb in directory "app/model/concerns/" which holds all the options of the checkbox as an array that can be edited easily.
In app/model/concerns/mobilephones_data.rb I wrote:
module Mobilenphones_Data
Activities = [
'Amazon Kindle', 'Blackberry', 'iPad', 'iPhone', 'Mobile Phone', 'Nokia',
'Palm', 'Samsung'
]
end
This will put all data from module's array into the checkbox drop-down as checkbox options. In My form I did:
<div class="card">
<a class="card-link card-header" data-toggle="collapse" href="#collapseOne">
Mobile Phones
</a>
<div id="collapseOne" class="collapse" data-parent="#accordion">
<div class="card-body">
<% Mobilenphones_Data::Activities.each do |activity| %>
<div id="skill_list" class="col-lg-3 col-md-4 col-sm-12 col-12">
<%= f.check_box :skills, { multiple: true }, activity, false %>
<%= activity %>
</div>
<% end %>
</div>
</div>
</div> <!--bottom-->
</div>
In my view "show.html.erb":
<% #name_of_model.skills.each do |skill| %>
<%= skill %>
<% end %>
For posterity sake:
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= f.label "Select a Product" %><br />
<%= f.check_box(:option) %>
<%= f.label(:mug, "Option") %><br />
<%= f.check_box(:option2) %>
<%= f.label(:mousepad, "Option2") %>
</div>
</div>
</div>

How to pass parameters in controller in Ruby On Rails

I am trying to pass parameters in controller but it is not returning anything.Please help me how I can pass parameters .
Controller Code -
def print_salary_slip_monthwise
#month = params[:salary][:month]
#year = params[:salary][:year]
#company = params[:salary][:company_id]
#company_location = params[:salary][:company_location_id]
#department = params[:salary][:department_id]
#salaryslips = Salaryslip.where(month: #month,year: #year.to_s,employee_id: #salary1)
end
form.html.erb - This is my form in which I used on change event .
<div class="box">
<div class="box-header">
<h3 class="box-title">Salary Slip Department Wise</h3>
</div><!-- /.box-header -->
<div class="box-body">
<%= bootstrap_form_for(:pdf_salaries, url: { action: 'print_salary_slip_monthwise'},html: {id: 'pdf_salaries'},remote: true ) do |f| %>
<div class="row">
<div class="col-sm-2">
<label>Year</label>
<div class="field">
<%= select :salary,:year,['2015','2016','2017','2018','2019','2020','2021','2022','2023','2024','2025','2026','2027'],{label: 'Select Year',include_blank: " Select Year"},{class: 'form-control'} %>
</div>
</div>
<div class="col-sm-2">
<label>Month</label>
<div class="field">
<%= select :salary,:month, ['January','February','March','April','May','June','July','August','September','October','November','December'],{label: 'Select Month',include_blank: " Select Month"}, class: "form-control" %>
</div>
</div>
<div class="col-sm-2">
<div class="form-group required">
<div class="input-group">
<%= f.select :company_id, all_company,{include_blank: "Select Company"},{onchange:"var a={id:$(this).val(), form : 'employee'}; $.get('/employees/collect_company_location',a,function(response){});"}%>
</div>
</div>
</div>
<div class="col-sm-2">
<div class="form-group required">
<div id="company_location">
<%= render 'employees/company_location_dropdown' %>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="form-group required">
<div class="input-group">
<div id="department">
<%= render 'employees/department_dropdown' %>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-2">
<div class="actions">
<%= f.submit "Display Report", class: "btn btn-sm btn-primary",id: "buttonCtc" %>
</div>
</div>
</div>
<div class="ajax-progress"></div>
<div id="employee_list_pdf"></div>
</div>
</div>
<%end%>
You can pass parameters using form or using ajax. Once you pass a parameters to your server (controller) you can check it to your server log to see the parameters. In rails 4 you need to use Strong Parameters to save these parameters to your database.
Take this as an example of the Form will below field.
<%= simple_form_for #user do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
When above form will be submitted. you can see the rails server terminal for params
Parameters: {"user"=>{"username"=>"user1", "password"=>"password"}, "commit"=>"Submit"}
Access params in controller like this:
params[:user][:username] # code in controller
Hope this give you the clear understaning.

Rails form populated from one table and saving to another

Title kinda says it all, Basically i have this form
<% provide(:title, "Edit user") %>
<h1>Editing event:
<%= #newevent.id %></h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= simple_form_for #newevent do |f| %>
<div class="form-group">
<%= f.label :eventname %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :eventname, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<%= f.input :event_type, :collection => ['Concert','Festival','Sports','Theatre'] %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :eventdesc %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :eventdesc, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :eventshortdesc %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :eventshortdesc, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :pagetitle %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :pagetitle, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :metatag %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :metatag, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :eventvenuename %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :eventvenuename, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<%= f.input :time, type: "time", :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<%= f.input :date, type: "date", :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :eventimage %>
<div class="row">
<div class="col-md-6">
<%= f.text_field :eventimage, :autofocus => true, class: "form-control" %>
</div>
</div>
</div>
<%= f.submit "Save changes", class: "btn btn-info" %>
<%= link_to "Delete", event_path(#newevent), :method => :delete, class: "btn btn-danger" %>
<% end %>
</div>
</div>
Here is what it loads from.
def edit
#newevent = Event.find(params[:id])
end
However its different now. I am wanting the stuff to load form the Master table (so the fields are populated from Master) However i have an update method that looks like this
def update
#newevent = Event.find(params[:id])
if #newevent.update_attributes(event_params.merge createdby: current_user.id)
flash[:success] = "Profile updated"
redirect_to "/events"
else
flash.now[:alert] = 'Error updating event'
end
end
Do i need to change something in the eventparams to get this to work (and make change from Event to Master) The fields are different in both tables, So would i need to make the value of the fields be something like this?
value: "<%=Master.name%>"
Thanks
Sam
If you're trying to load "defaults", you'd be better doing it in the model layer:
#app/models/event.rb
class Event < ActiveRecord::Base
before_create :set_defaults
private
def set_defaults
default = Master.first
self.attributes.except("id", "created_at", "updated_at").each do |field|
self[field] ||= default.send(field)
end
end
end
The above will pull a record from the Master model, populate any of the attributes in your Event model which have not been populated.
However, I believe your pattern to be inefficient.
The idea you are pulling "default" data from another model/table directly contradicts the DRY and modular principles of software development.
Not to say that if you wanted to create "dynamic" defaults for a model, your pattern might work. If you're trying to store exactly the same data in different models, you've got a problem.
I would do the following:
#app/models/event.rb
class Event < ActiveRecord::Base
##defaults: {
x: "y",
y: "z",
z: "0"
}
before_create :set_defaults
private
def set_defaults
self.attributes.except("id", "created_at", "updated_at").each do |field|
self[field] ||= ##defaults[field]
end
end
end
Update
After a discussion, it became apparent that there was more context required to understand the issue/solution fully.
The app works by importing a series of CSV data into the Master table. Whilst I don't know what data this is, the OP said that each Event would be built around the data in Master.
He mentioned he needed 3 fields definitely from Master whilst the others could be inputted by the user into Event.
This means that you could tie the two together with a has_many / belongs_to relationship:
#app/models/master.rb
class Master < ActiveRecord::Base
has_many :events
end
#app/models/event.rb
class Event < ActiveRecord::Base
belongs_to :master
end
This is a standard ActiveRecord association, which means you'll be able to call #master.events & #event.master -- accessing values from each table:
#app/controllers/events_controller.rb
class EventsController < ApplicationController
def new
#event = Event.new
end
def create
#event = Event.new event_params
#event.save
end
private
def event_params
params.require(:event).permit(:master_id, ...)
end
end
#app/views/events/new.html.erb
<%= form_for #event do |f| %>
<%= f.collection_select :master_id, Master.all, :id, :name %>
<%= f.submit %>
<% end %>
--
The reason why this will be much better than your current pattern is that each time you create a new event, you'll be able to access the master attributes:
#event.master.url #-> "url" from master record
In Rails in general you create bound form inputs by using a model and passing it to form_for (or simple_form_for).
In this case if you really need to have dynamic user editable default the most obvious solution would be to use Master to seed the new Event.
In most cases however defaults should be a developer concern which are handled on the model layer as suggested by Rich Peck.
Also setting defaults only really makes sense for a new record - why would you want to override the users choices when updating?
def new
#master = Master.last
#event = Event.new(#master.attributes.except("id", "created_at", "updated_at"))
end
<%= simple_form_for #newevent do |f| %>
<%= f.input :eventname %>
<% end %>

Trying to initiate a variable on page load Angularjs

I am trying to initiate a variable showName when the page loads. It worked fine when I did it using just angular but when I implemented it with rails(with embedded ruby tags) I am not able to hide the text field and save button as my variable gets undefined. I have tried couple of ways and ended with no result.
Here is my code. Any help is really appreciated. Thanks.
Edit.html.erb:
<div class="row" ng-controller="EditUserCtrl">
<div class="col-md-6 col-md-offset-3" id="editForm">
<%= form_for(#user) do |f| %>
<h1 id="editHeader">Account Information </h1>
<%= render 'shared/error_messages' %>
<div class="form-group">
<%= f.label :name, "Full Name:" %><br>
<div class="row">
<div class="col-sm-7">
<div ng-hide="showName">
<%= f.label :name, #user.name , id:"editFields" %>
</div>
<%= f.text_field :name, { :'ng-show' => 'showName'}%>
</div>
<div class="col-sm-5" ng-show="showName">
<%= f.button "Save", :action => "update_name" , :method => :put, class: "btn btn-primary", :'ng-click' => "clicked()", id:"editAccount" %>
</div>
<div class="col-sm-5" ng-hide="showName">
<i id="nav-cart-count" class="glyphicon glyphicon-edit"></i> Edit
</div>
</div>
</div>
<% end %>
</div>
Use ng-init to initialize the variable
<div class="row" ng-controller="EditUserCtrl" ng-init="showName = true">

Error on User Authentication not working

I have a sessions_helper file that finds a user and if the user is found logins to the application. However, if the user is not found, it should give an error.
module SessionsHelper
# Log a user in after authenticating, store in session
def log_in(user)
if user.id.nil?
format.html { redirect_to signin_path, notice: 'Invalid Email or password' }
format.json { head :no_content }
else
session[:user_id] = user.id
end
end
end
I have a sessions/unauth view.
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">Log In!</div>
<div class="panel-body">
<%= form_for(:credentials, url: signin_path) do |f| %>
<div class="form-group">
<%= f.label :email%>
<%= f.email_field :email, class: 'form-control'%>
</div>
<div class="form-group">
<%= f.label :password%>
<%= f.password_field :password, class: 'form-control'%>
</div>
<%= submit_tag %>
<% end %>
</div>
</div>
</div>
This code allows user to login to app successfully, but if user is not found does not display an error on the application.
you need to include this into your view
<% if flash[:notice] %>
<div class="notice"><%= flash[:notice] %></div>
<% end %>
this code will display your error message.
read here
You've not published the flash message in the view.
--
Flash
The Rails Flash is a type of session variable used to store data generated in actions. It's means to give you the ability to call alerts / notices in either the view or layout.
There are 3 types of flash, although I think you can use as many as you wish:
notice
alert
error
When you call ... notice: 'Invalid Email or password' }, you're telling rails to populate the flash[:notice] object.
If you want to show this in your view, you need to invoke it, as following:
<div class="col-md-4">
<div class="panel panel-default">
<!-- Error -->
<%= flash[:notice] if flash[:notice] %>
<!-- Login -->
<div class="panel-heading">Log In!</div>
<div class="panel-body">
<%= form_for(:credentials, url: signin_path) do |f| %>
<div class="form-group">
<%= f.label :email%>
<%= f.email_field :email, class: 'form-control'%>
</div>
<div class="form-group">
<%= f.label :password%>
<%= f.password_field :password, class: 'form-control'%>
</div>
<%= submit_tag %>
<% end %>
</div>
</div>
</div>

Resources