I am trying to implement the railscast (http://railscasts.com/episodes/217-multistep-forms?view=asciicast) within a modal window.
I am receiving the fatal (exception reentered) error message after I click submit on my first page. I believe that it is getting stuck somewhere .next_step.
I am using a modal window that calls new.js.erb and . I will add additional code as needed. Sorry for creating the question improperly.
---Code:
Model:
estimate.rb
class Estimate < ApplicationRecord
attr_writer :current_step
has_many :estimateitems
def current_step
#current_step || current_step.first
end
def next_step
self.current_step = steps[steps.index(current_step + 1)]
end
def steps
%w[1st 2nd]
end
end
Views:
new.js.erb
// Add the dialog title
$('#dialog h3').html("<i class='glyphicon glyphicon-plus'></i> New Estimate");
// Render the new form
$('.modal-body').html('<%= j render("clients/partials/form_create_estimate") %>');
// Show the dynamic dialog
$('#dialog').modal("show");
// Set focus to the first element
$('#dialog').on('shown.bs.modal', function () {
$('.first_input').focus()
})
form_create_estimate.html.erb
<%= form_for(#estimate, remote: true, :html => { :role => "form" }, :'data-update-target' => 'update-container') do |f| %>
<% if #estimate.current_step = 1 %>
<%= render '1st_step', :f => f %>
<% elsif #estimate.current_step = 2 %>
<%= render '2nd_step', :f => f %>
<% end %>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
Controllers:
class EstimatesController < ApplicationController
before_action :logged_in_user, only: [:index, :show, :edit, :update, :destroy]
before_action :set_estimate, only: [:show, :edit, :update, :destroy]
def index
#estimates = Estimate.all
end
def show
end
def new
#estimate = Estimate.new
end
def edit
end
def create
#estimate = Estimate.new(params[:estimate_params])
#estimate.next_step
render 'new'
end
def update
respond_to do |format|
if #estiamte.update_attributes(estimate_params)
format.json { head :no_content }
format.js
else
format.json { render json: #estimate.errors.full_messages, status: :unprocessable_entity }
end
end
end
def destroy
#estimate.destroy
respond_to do |format|
format.js
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
private
def set_estimate
#estimate = Estimate.find_by(id: params[:id])
end
def estimate_params
params.require(:estimate).permit(:nickname, :date)
end
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
end
Related
class User < ActiveRecord::Base
has_one :comapny
end
class Comapny < ApplicationRecord
belongs_to :user
end
Hi! i created rails association mentioned above. I want user to create only one company (for example: User with id(1) should only make 1 company only).
But even with has_one i am able to make more then 1 company for user1.
can anyone help?
user_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:edit, :update, :show]
before_action :require_user, only: [:index, :show, :update ]
before_action :require_same_user, only: [:edit, :destroy, :update]
before_action :require_admin, only: [:destroy]
def index
#user = User.all
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
flash[:success] = "Welcome #{#user.username}"
redirect_to user_path(#user)
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
flash[:success] = "Account was updated"
else
render 'new'
end
end
def show
end
def destroy
#user = User.find(params[:id])
#user.destroy
flash[:danger] = "User is destroyed"
redirect_to root_path
end
private
def user_params
params.require(:user).permit(:username, :email, :password, :role, :first_name, :last_name)
end
def set_user
#user = User.find(params[:id])
end
def require_same_user
if current_user != #user and !current_user.admin?
flash[:danger] = "Not authorized"
redirect_to user_path
end
end
def require_admin
if logged_in? and !current_user.admin?
flash[:danger] = "Not authorized"
redirect_to user_path
end
end
end
**comapny_controller.rb**
class ComapniesController < ApplicationController
before_action :set_comapny, only: %i[ show edit update destroy ]
before_action :require_user, only: [:create]
# GET /comapnies or /comapnies.json
def index
#comapnies = Comapny.all
end
# GET /comapnies/1 or /comapnies/1.json
def show
end
# GET /comapnies/new
def new
#comapny = Comapny.new
end
# GET /comapnies/1/edit
def edit
end
# POST /comapnies or /comapnies.json
def create
#comapny = Comapny.new(comapny_params)
respond_to do |format|
if #comapny.save
format.html { redirect_to comapny_url(#comapny), notice: "Comapny was successfully created." }
format.json { render :show, status: :created, location: #comapny }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #comapny.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comapnies/1 or /comapnies/1.json
def update
respond_to do |format|
if #comapny.update(comapny_params)
format.html { redirect_to comapny_url(#comapny), notice: "Comapny was successfully updated." }
format.json { render :show, status: :ok, location: #comapny }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #comapny.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comapnies/1 or /comapnies/1.json
def destroy
#comapny.destroy
respond_to do |format|
format.html { redirect_to comapnies_url, notice: "Comapny was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comapny
#comapny = Comapny.find(params[:id])
end
# Only allow a list of trusted parameters through.
def comapny_params
params.require(:comapny).permit(:name, :year_founded, :user_id)
end
end
**Coampny_form.html.erb**
<%= form_with(model: comapny, local: true) do |form| %>
<% if comapny.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(comapny.errors.count, "error") %> prohibited this comapny from being saved:</h2>
<ul>
<% comapny.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name, id: :comapny_name %>
</div>
<div class="field">
<%= form.label :year_founded %>
<%= form.date_select :year_founded, id: :comapny_year_founded %>
</div>
<div class="field">
<%= form.label :user_id %>
<%= form.text_field :user_id, id: :comapny_user_id, value: current_user.id %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
I made a typo while generating scaffold of coapmny instead of company. ignore that
Add a uniqueness constraint to the db table and a uniqueness validation to the company model:
class Comapny < ApplicationRecord
belongs_to :user
validates :user_id, uniqueness: true
end
Here i have a project to which i am adding a session and for a project session i am trying to add task.
i am able to create project and add project session for project but when i am trying to add task for session using project_sessions_id i am getting error Couldn't find ProjectSession with 'id'= and 'app/controllers/tasks_controller.rb:60:in set_project_session i am able to get the project session id also project_sessions/11 in the url but when i click 'create task' i am getting this error. how can i resolve this?
here's what i have done
ProjectSessionController:
class ProjectSessionsController < ApplicationController
before_action :set_project_session, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :set_project
def index
#project_sessions = ProjectSession.all
end
def show
#project_sessions = ProjectSession.where(project_id: #project.id).order("created_at DESC")
end
def new
#project_session = ProjectSession.new
end
def edit
end
def create
#project_session = ProjectSession.new(project_session_params)
#project_session.project_id = #project.id
#respond_to do |format|
if #project_session.save
redirect_to #project
#format.html { redirect_to #project_session, notice: 'Project session was successfully created.' }
#format.json { render :show, status: :created, location: #project_session }
else
format.html { render :new }
format.json { render json: #project_session.errors, status: :unprocessable_entity }
end
#end
end
def update
respond_to do |format|
if #project_session.update(project_session_params)
format.html { redirect_to #project_session, notice: 'Project session was successfully updated.' }
format.json { render :show, status: :ok, location: #project_session }
else
format.html { render :edit }
format.json { render json: #project_session.errors, status: :unprocessable_entity }
end
end
end
def destroy
#project_session.destroy
respond_to do |format|
format.html { redirect_to project_sessions_url, notice: 'Project session was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project_session
#project_session = ProjectSession.find(params[:id])
end
def set_project
#project = Project.find(params[:project_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_session_params
params.require(:project_session).permit(:session_date, :session_name, :session_description, :start_time, :end_time)
end
end
Task controller:
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :set_project_session
def index
#tasks = Task.all
end
def show
end
def new
#task = Task.new
end
def edit
end
def create
#task = Task.new(task_params)
#task.session_id = #project_session.id
respond_to do |format|
if #task.save
redirect_to #project_session
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_task
#task = Task.find(params[:id])
end
def set_project_session
#project_session = ProjectSession.find(params[:project_session_id])
end
def task_params
params.require(:task).permit(:name, :description)
end
end
routes:
Rails.application.routes.draw do
get 'hr_dashboard/index'
resources :roles
resources :project_sessions
devise_for :users
resources :tasks
resources :projects do
resources :project_sessions, except: [:show, :index]
end
resources :project_sessions do
resources :tasks, except: [:show, :index]
end
authenticated :user do
root 'admindashboard#index', as:"authenticated_root"
end
root 'welcome#index'
get 'userdashboard/index'
get 'admindashboard/index'
get 'welcome/index'
end
View for creating new task
<div class="container">
<h1>New Task</h1>
<%= form_for(#task) do |f| %>
<% if #task.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#task.errors.count, "error") %> prohibited this task from being saved:</h2>
<ul>
<% #task.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Back', tasks_path %>
</div>
I figured it out!
I had forgotten to add #project_session in
<%= form_for([#project_session, #task]) do |f| %>
just added that and it worked.
In your create action of Task controller, you have to add:
#task= #project_session.tasks.build(task_params)
Because right now, you're not telling the task, to build from the project_session (or with respect to the project_session) you're just telling it to create a new task.
#task = Task.new
And in the routes.rb file, you've prepared for that to happen by nesting the resources, so it's currently looking for the ID of a task that belongs_to project_session. But can't find any.
And also, in your form_for element when creating a ProjectSssion you have let that form know which route it should belong to - I guess you could say - since you still have the un-nested resources available:
resources :tasks
If project_sessions shouldn't be creatable without a parent, there's no reasons for keeping that, so you should just remove it.
Anyways, here's what the form_for should look like:
<%= form_for([#project_session, #task]) do |f| %>
I am using simple form for a nested resource.
resources :users do
resources :interests
end
I have the following call-backs in my InterestsController
class InterestsController < ApplicationController
before_action :set_interest, only: [:show, :create, :edit, :update, :destroy]
before_action :set_user, only: [:index, :show, :create, :edit, :update, :destroy]
private
# Use callbacks to share common setup or constraints between actions.
def set_interest
#interest = Interest.find(params[:id])
end
def set_user
#user = current_user
end
end
I have a simple form - this works......
<%= simple_form_for [:user, #interest] do |f| %>
<% if #interest.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#interest.errors.count, "error") %> prohibited this response from being saved:</h2>
<ul>
<% #interest.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-inputs">
<%= f.input :user_id %>
<%= f.input :discipline_id %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
But this does not.....
<%= simple_form_for [#user, #interest] do |f| %>
I can find no explanation for this - surely #user in the simple form is the correct was to declare the User?
Here is more information:
This is the error I get for the edit action:
No route matches {:action=>"show", :controller=>"interests", :format=>nil, :id=>nil, :user_id=>#<Interest id: 1, user_id: 1, discipline_id: 10, created_at: "2015-02-22 11:00:14", updated_at: "2015-02-22 11:00:14">} missing required keys: [:id]
Interestingly, the new action works. If I switch the simple form to
<%= simple_form_for [#user, #interest] do |f| %>
The edit action works but the new action does not. So I am guessing this has to be the way I have my InterestsController set up.
Here it is in full.
class InterestsController < ApplicationController
before_action :set_interest, only: [:show, :create, :edit, :update, :destroy]
before_action :set_user, only: [:index, :show, :create, :edit, :update, :destroy]
def index
#users_interests = #user.interests
end
def show
end
def new
#interest = current_user.interests.new
end
def edit
end
def create
#interest = User.find(params[:user_id]).interests.build(interest_params)
#interest.user = current_user
respond_to do |format|
if #interest.save
flash[:success] = "Interest created!"
format.html { redirect_to user_interests_path(current_user) }
format.json { render :show, status: :created, location: #interest }
else
flash[:failure] = "Interest was not added!"
format.html { render :new }
format.json { render json: #interest.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #interest.update(interest_params)
format.html { redirect_to user_interests_path(current_user) }
format.json { render :show, status: :ok, location: #interest }
else
format.html { render :edit }
format.json { render json: #interest.errors, status: :unprocessable_entity }
end
end
end
def destroy
#interest.destroy
respond_to do |format|
format.html { redirect_to interests_url, notice: 'Interest was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_interest
#interest = Interest.find(params[:id])
end
def set_user
#user = current_user
end
# Never trust parameters from the scary internet, only allow the white list through.
def interest_params
params.require(:interest).permit(:user_id, :discipline_id)
end
end
SOLVED:
easy fix - need to set #user = current_user in the new action:
def new
#interest = current_user.interests.new
#user =current_user
end
I am having 2 models:
app/models/employee.rb:
class Employee < User
has_many :insurances
end
app/models/insurance.rb:
class Insurance < ActiveRecord::Base
belongs_to :employee
end
app/controllers/employees_controller.rb:
class EmployeesController < ApplicationController
before_action :set_employee, only: [:show, :edit, :update, :destroy]
before_action :employee_params, only: [:create, :update]
# GET /employees
# GET /employees.json
def index
#employees = Employee.all
end
# GET /employees/1
# GET /employees/1.json
def show
#employee = Employee.find(params[:id])
end
# GET /employees/new
def new
#employee = Employee.new
end
# GET /employees/1/edit
def edit
#employee = Employee.find(params[:id])
end
# POST /employees
# POST /employees.json
def create
#employee = Employee.new(employee_params)
respond_to do |format|
if #employee.save
format.html { redirect_to employees_url, notice: "#{#employee.first_name} was successfully created." }
format.json { render :index, status: :created, location: #employee }
else
format.html { render :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 employees_url, notice: "#{#employee.first_name} was successfully updated."}
format.json { render :index, status: :ok, location: #employee }
else
format.html { render :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, notice: 'Employee was successfully destroyed.' }
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
if params[:employee][:password].blank? && params[:employee][:password_confirmation].blank?
params[:employee].delete(:password)
params[:employee].delete(:password_confirmation)
end
params[:employee].permit(:email, :password, :employee_id,:employee_work_id, :first_name, :middle_name, :last_name, :gender, :date_of_birth, :driver_license_no, :driver_license_expiry_date, :martial_status, :nationality, :office_address, :residence_address, :city, :state_province, :zip_code, :country, :work_number, :mobile_number, :home_number, :other_email)
end
end
app/controllers/insurance_controller.rb:
class InsurancesController < ApplicationController
before_action :set_insurance, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#insurances = Insurance.all
respond_with(#insurances)
end
def show
respond_with(#insurance)
end
def new
#insurance = Insurance.new
respond_with(#insurance)
end
def edit
end
def create
#insurance = Insurance.new(insurance_params)
#insurance.save
respond_with(#insurance)
end
def update
#insurance.update(insurance_params)
respond_with(#insurance)
end
def destroy
#insurance.destroy
respond_with(#insurance)
end
private
def set_insurance
#insurance = Insurance.find(params[:id])
end
def insurance_params
params.require(:insurance).permit(:employee_id,:name_of_dependent, :relationship, :name, :of_spouse, :children, :date_of_birth, :policy_number, :policy_provider, :policy_type)
end
end
app/views/insurances/_show.html.erb:
<%= employee.insurances.each do |emp| %>
<p>
<strong>Name of dependent:</strong>
<%= emp.name_of_dependent %>
</p>
<p>
<strong>Name:</strong>
<%= emp.name %>
</p>
<% end %>
When i use link_to with show path, it is working fine.
app/views/employees/show.html.haml:
%p
%strong Title:
= #employee.full_name
%p
%strong Text:
= #employee.gender
%p
= link_to 'Insurance', insurance_path
after accordion code, i used render as follows:
%p
%strong Title:
= #employee.full_name
%p
%strong Text:
= #employee.gender
%p
#accordion2.panel-group
#new-student-widget.panel.panel-default.left-column-entry
.header.panel-heading
.header-content.panel-title
%a#newStudentToggle{"data-parent" => "#accordion2", "data-target" => "#newStudent", "data-toggle" => "collapse"} Insurance Details
#newStudent.panel-collapse.collapse
#newStudentInner.panel-body
= render :template => 'insurances/show', locals: { employee: #employee }
When i am using render in accordion, i am getting error as:
NoMethodError in Employees#show
undefined method `name_of_dependent' for nil:NilClass
Please help me out.
If you are calling show as partial then rename show.html to _show.html
and pass #employeee instance variable which is present in accordion code
= render :template => 'insurances/show', locals: { employee: #employee }
and in _show page
- employee.insurances.each do |ins|
%p.strong Name of dependent:
= ins.name_of_dependent
%p.strong Name:
= ins.name
Pass the insurance object when you are rendering the template :
- #insurances.each do |insurancce|
= render template: 'insurances/show', locals: { insurance: insurance }
- end
Make sure you instantiated the #insurance object in your controller action, where you instantiated the #employee object.
#employee = current_user # or anything else
#insurances = #employee.insurances
Then in your Insurances#show template use insurance instead of #insurance like this :
<p id="notice"><%= notice %></p>
<p>
<strong>Name of dependent:</strong>
<%= insurance.name_of_dependent %>
</p>
<p>
<strong>Name:</strong>
<%= insurance.name %>
</p>
I'm trying to list all the posts of the current_user in a view not associated with the posts controller. I tried doing it but can't seem to wrap my head around it
posts_controller.rb
class PostsController < ApplicationController
before_action :authenticate_user!
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
#posts = Post.paginate(:page => params[:page], :per_page => 5, :order => 'id DESC')
end
def show
end
def new
#post = Post.new
end
def edit
end
def create
#post = Post.new(post_params)
#post.email = current_user.username
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
#protect_from_forgery with: :null_session #i added this from SO!!!!!!!!!!!!!!!!!!
before_filter :configure_permitted_parameters, if: :devise_controller?
helper_method :mypost
def mypost
#mypost = Post.all
#mypost = Post.paginate(:page => params[:page], :per_page => 5, :order => 'id DESC')
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
devise_parameter_sanitizer.for(:account_update) << :username
end
end
in the view of new site
<% #mypost.each do |mypost| %>
<%= link_to post do %>
<div id="rectmine">
<h1><%= post.title %></h1>
<p><%= post.author %><p>price: <%= post.price %></p> location: <%= post.school %>
<hr style="width: 505px;">
<% end %>
<% if current_user.email == post.email %>
<p>This is your post! Feel free to edit or delete it. -> </p>
<%= link_to 'Edit', edit_post_path(post) %>
<%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
<% end %>
Return the new variable from the helper.
helper_method :get_post_paginate
def get_post_paginate
#mypost = Post.paginate(:page => params[:page], :per_page => 5, :order => 'id DESC')
#mypost
end
And use the method call in the view
<% get_post_paginate.each do |mypost| %>
Why don't you place the code in the controller you are calling. For example, if you call the index action of your NoPostsController you can place the code within that action and it should work fine. Seems weird to me to place a query within a helper, that logic does not belong there in my opinion.
The only thing you want is that current user is accessible in every controller.