RoR: Param is missing or the value is empty - ruby-on-rails

I am getting an error when I try to update a prop(which is like an article). I can create a prop but when I go to edit it I get the following error:
This is my props controller:
class PropsController < ApplicationController
attr_accessor :user, :answer, :choice, :prop
def index
#props=Prop.all
end
def show
#prop = Prop.find(params[:id])
end
def new
#prop = Prop.new
#user = User.find(session[:user_id])
end
def edit
#prop = Prop.find(params[:id])
#user = User.find(session[:user_id])
#answer = #user.answers.update(prop_params)
end
def create
#prop = Prop.new(prop_params)
#user = User.find(session[:user_id])
#answer = Answer.new
if #prop.save
redirect_to #prop
else
render 'new'
end
end
def update
#user = User.find(session[:user_id])
#prop = Prop.find(params[:prop_id])
#answer = #user.answers.update(answer_params)
if #prop.update(prop_params)
redirect_to #prop
else
render 'edit'
end
if #answer.choice == #prop.choice
puts "hello"
#user.score += 7
#user.save
else
#user.score -= 7
#user.save
end
end
def destroy
#prop = Prop.find(params[:id])
#prop.destroy
redirect_to props_path
end
def select
#prop = Prop.find(params[:choice])
end
end
private
def prop_params
params.require(:prop).permit(:title, :text, :choice, :user_id, :id)
end
def answer_params
params.require(:answer).permit(:choice, :id, :prop_id, :user_id)
end
This is my form. It is a partials shared between the new and edit views:
<%= form_for #prop do |f| %>
<% if #prop.errors.any? %>
<div class="error_explanation">
<h2>
<%= pluralize(#prop.errors.count, "error") %>
prohibited this prop from being saved:
</h2>
<ul>
<% #prop.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<%= f.radio_button(:choice, "A") %>
<%= f.label(:choice, "The Correct Answer is A") %>
<%= f.radio_button(:choice, "B") %>
<%= f.label(:choice, "The Correct Answer is B") %>
<%= f.radio_button(:choice, "C") %>
<%= f.label(:choice, "The Answer Has Yet To Be Determined") %>
<%= f.hidden_field :user_id, :value => #user.id %>
<p>
<%= f.submit %>
</p>
<% end %>

Can you please change your update action as:
def update
#user = User.find(session[:user_id])
#prop = Prop.find(params[:prop_id].merge(:user_id => #user))
#answer = #user.answers.update(answer_params)
if #prop.update(prop_params)
redirect_to #prop
else
render 'edit'
end
if #answer.choice == #prop.choice
puts "hello"
#user.score += 7
#user.save
else
#user.score -= 7
#user.save
end
end
and your prop params as:
def prop_params
params.require(:prop).permit(:title, :text, :choice, :id)
end
This helps in sending the user_id into the prop table by using merge method. Try this I hope this could resolve your issue and make sure you change your create action to send the user_id into prop table.

Related

Ruby Rails Sort Index List of users by most recent review

I have a list of users that post reviews. I'm trying to make the list sortable in different ways. I'm stuck on sorting the list by each user's most recent review.
My current approach is to make a model scope. I'm just not getting it.
This is the model:
class User < ApplicationRecord
attr_accessor :password
validates_confirmation_of :password
validates :email, :presence => true, :uniqueness => true
validates :user_name, :presence => true, :uniqueness => true
before_save :encrypt_password
has_many :reviews
has_one_attached :avatar_pic
scope :users_most_recent, -> {(
select('users.id, users.user_name')
.joins(:reviews).where('reviews.updated_at')
.group('users.id')
.order('updated_at DESC')
)}
def self.user_reviews(user_id)
#user_reviews = Review.where(user_id: user_id).count
end
def self.user_ave_rating(user_id)
_average_reviews = []
_rev_count = 0
_new_average = 0.0
_average_reviews = Review.where(user_id: user_id)
_average_reviews.each do |average_review|
_rev_count += average_review.rating
end
_new_average = (_rev_count / _average_reviews.length.to_f).round(1)
end
def self.user_latest_review(user_id)
#latest_review = Review.where(user_id: user_id).where('created_at < ? ', Time.now).order('created_at DESC').first
if #latest_review.nil?
last_review = {}
else
last_review = #latest_review.created_at.strftime('%m-%d-%Y')
end
end
def encrypt_password
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password,password_salt)
end
def self.authenticate(email, password)
user = User.find_by "email = ?", email
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
end
This is the controller, the index is where I'm trying to implement this:
class UsersController < ApplicationController
before_action :current_user, only: [:show, :edit, :update, :destroy]
def new
#user = User.new
end
def create
#user = User.new(user_params)
#user.avatar_pic.attach(params[:user][:avatar_pic])
if #user.save
flash[:notice] = "You've successfully signed up!"
session[:user_id] = #user.id
redirect_to "/"
else
flash[:alert] = "There was a problem signing up."
redirect_to '/signup'
end
end
def show
#user = current_user
render :show
end
def edit
#user = current_user
render :edit
end
def update
#user = current_user
if #user.update(user_params)
flash[:notice] = "Profile successfully updated!"
redirect_to user_path(#user)
else
render :edit
flash[:notice] = "Something went wrong. Please contact Mario's technical assistance staff."
end
end
def index
case
when params[:az]
#users = User.order('user_name').paginate(page: params[:page], per_page: 20)
when params[:za]
#users = User.order('user_name DESC').paginate(page: params[:page], per_page: 20)
when params[:high_rating]
"High Rating"
when params[:low_rating]
"Low Rating"
when params[:most_reviews]
"Most Reviews"
when params[:least_reviews]
"Least Reviews"
when params[:most_recent]
#users = User.users_most_recent.paginate(page: params[:page], per_page: 20)
when params[:least_recent]
"Least Recent"
else
#users = User.all.paginate(page: params[:page], per_page: 20)
end
render :index
end
private
def user_params
params.require(:user).permit(:email, :user_name, :password, :password_confirmation, :admin, :avatar_pic)
end
end
This is my view:
<p id="notice"><%= notice %></p>
<div class="sort-flex-wrapper">
<h1 class="center">Our Community</h1>
<div class="btn-group sort-button">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sort By
</button>
<div class="dropdown-menu">
<%= link_to "User Name A-Z", users_path(:az => 'az'), class: "dropdown-item" %>
<%= link_to "User Name Z-A", users_path(:za => 'za'), class: "dropdown-item" %>
<%= link_to "Highest Average Rating", users_path(:high_rating => 'high_rating'), class: "dropdown-item" %>
<%= link_to "Lowest Average Rating", users_path(:low_rating => 'low_rating'), class: "dropdown-item" %>
<%= link_to "Most Reviews", users_path(:most_reviews => 'most_reviews'), class: "dropdown-item" %>
<%= link_to "Least Reviews", users_path(:least_reviews => 'least_reviews'), class: "dropdown-item" %>
<%= link_to "Most Recent Review", users_path(:most_recent => 'most_recent'), class: "dropdown-item" %>
<%= link_to "Least Recent Review", users_path(:least_recent => 'least_recent'), class: "dropdown-item" %>
</div>
</div>
</div>
<div class="community-flex-container">
<% if #users.any? %>
<% #users.each do |user| %>
<div class="community-profile-card">
<div class="community-profile-flex">
<div class="community-profile-box1">
<% if user.avatar_pic.attached? %>
<%= image_tag user.avatar_pic, class:"avatar" %><br>
<% else %>
<%= image_tag 'generc_profile_pic.webp', class:"avatar", alt: 'Avatar Not Found ' %><br>
<% end %>
</div>
<div class="community-profile-box2">
<div class="community-column-box1">
<% if user.user_name? %>
<h3><%= user.user_name %></h3>
<% else %>
<h3>Guest User</h3>
<% end %>
</div>
<div class="community-column-box2">
<div class="community-align-stars">
<p>Average Rating: </p>
</div>
<div class="community-align-stars">
<div class="star-align">
<%= render partial: "shared/review_stars", locals: { review: User.user_ave_rating(user.id) } %>
</div>
</div>
</div>
<div class="community-column-box3">
<p>Number of Reviews: <%= User.user_reviews(user.id) %></p>
</div>
<div class="community-column-box4">
<% if User.user_latest_review(user.id) == {} %>
<p>Most Recent Review: None</p>
<% else %>
<p>Most Recent Review: <%= User.user_latest_review(user.id) %></p>
<% end %>
</div>
</div>
</div>
</div>
<% end %>
<% else %>
<p>There are no users (yet).</p>
<% end %>
</div>
<div class="pagination">
<%= will_paginate #reviews%>
</div>
scope :users_most_recent, -> {(
select('users.id, users.user_name, max(reviews.updated_at) as reviews_updated_at')
.joins(:reviews)
.group('users.id')
.order('reviews_updated_at')
)}
Well, while we're at it we might as well fix the whole index method. You're doing to much in the controller, split it out to something like this:
class UserList
def self.order_users_by(order_value)
case order_value
when :az
User.order('user_name ASC')
when :za
User.order('user_name DESC')
when :high_rating
User.all.sort_by(&:average_rating).reverse
when :low_rating
User.all.sort_by(&:average_rating)
when :most_reviews
User.all.sort_by(&:review_count).reverse
when :least_reviews
User.all.sort_by(&:review_count)
else
User.all.sort_by(&:last_updated_review)
end
end
end
class User
def average_rating
(BigDecimal(reviews.sum(:rating).to_s) / BigDecimal(reviews.count.to_s)).round(1)
end
def review_count
reviews.count
end
def last_updated_review
reviews.order("updated_at")
end
end
class UsersController < ApplicationController
def index
UserList.order_users_by(params).paginate(page: params[:page], per_page: 20)
end
end

Rails 4 acts_as_follower

I have two models
Users and Groups
a am using gem acts_as_follower
https://github.com/tcocca/acts_as_follower
User.rb
class User < ActiveRecord::Base
has_many :groups
acts_as_follower
end
and Group.rb
class Group < ActiveRecord::Base
belongs_to :user
acts_as_followable
end
links to follow and unfollow
<% if current_user %>
<% if current_user.following?(#group) %>
<h2> <%= link_to 'Unfollow', unfollow_group_path(#group), class: 'fa fa-pause' %></h2>
<% else %>
<h2> <%= link_to 'Follow', follow_group_path(#group), class: 'fa fa-play' %></h2>
<% end %>
<% else %>
<%= link_to 'Login or Register to Follow', user_session_path, class: 'fa fa-unlock' %>
<% end %>
link to administration group followers
<h5>followers
<%= p #group.followers.count %></h5>
<% #group.followers.each do |follower| %>
<%= link_to user_path(follower) do %>
<%= image_tag(follower.image.url(:show), size: "40x40") %>
<% if current_user.id == #group.user.id %>
<%= link_to 'Reject', unfollow_group_path(#group , user_id:follower.id), class: ' fa fa-close' , style: 'color:red;' %>
<% end %>
<% end %>
<% end %>
<% if current_user.id == #group.user.id %>
<h5>expect</h5>
<% #followers_block.each do |block| %>
<%= link_to user_path(block.follower) do %>
<%= image_tag(block.follower.image.url(:show), size: "40x40") %>
<%= link_to 'Accept', follow_group_path(#group , user_id:block.follower.id), class: ' fa fa-close' , style: 'color:red;' %>
<% end %>
<% end %>
<% end %>
groups_controller.rb
def follow
#group = Group.find(params[:id])
if params[:user_id] && #group.user_id == current_user.id
#user = User.find(params[:user_id])
#user_block = Follow.where(followable_id: #group, followable_type: "Group" , follower_id: #user ).first
#user_block.update_attribute(:blocked, false)
#user_block.save
redirect_to :back
else
if current_user
current_user.follow(#group)
flash[:notice] = 'are now following'
else
flash[:error] = "You must login to follow "
end
redirect_to :back
end
end
def unfollow
#group = Group.find(params[:id])
if params[:user_id] && #group.user_id == current_user.id
#user = User.find(params[:user_id])
#user.stop_following(#group)
redirect_to :back
else
if current_user
current_user.stop_following(#group)
flash[:notice] = 'You are no longer following .'
else
flash[:error] = 'You to unfollow #'
end
redirect_to :back
end
end
how to add parameter (:blocked, true) this
if current_user
current_user.follow(#group)
flash[:notice] = 'are now following'
or this
<h2> <%= link_to 'Follow', follow_group_path(#group), class: 'fa fa-play' %></h2>
solved
if current_user
follow = current_user.follow(#group)
follow.update blocked: true
flash[:notice] = 'are now following'

How to call one model form field into another controller index?

Todos Controller
class TodosController < ApplicationController
# GET /todos
# GET /todos.json
def index
#todos = Todo.all
#projects = Project.new
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #todos }
end
end
# GET /todos/1
# GET /todos/1.json
def show
#todo = Todo.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #todo }
end
end
# GET /todos/new
# GET /todos/new.json
def new
#todo = Todo.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #todo }
end
end
# GET /todos/1/edit
def edit
#todo = Todo.find(params[:id])
end
# POST /todos
# POST /todos.json
def create
#todo = Todo.new(params[:todo])
respond_to do |format|
if #todo.save
format.html { redirect_to(#todo, :notice => 'Todo was successfully created.') }
format.json { render :json => #todo, :status => :created, :location => #todo }
else
format.html { render :action => "new" }
format.json { render :json => #todo.errors, :status => :unprocessable_entity }
end
end
end
# PUT /todos/1
# PUT /todos/1.json
def update
#todo = Todo.find(params[:id])
respond_to do |format|
if #todo.update_attributes(params[:todo])
format.html { redirect_to(#todo, :notice => 'Todo was successfully updated.') }
format.json { render :json => {} }
else
format.html { render :action => "edit" }
format.json { render :json => #todo.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /todos/1
# DELETE /todos/1.json
def destroy
#todo = Todo.find(params[:id])
#todo.destroy
respond_to do |format|
format.html { redirect_to(todos_url) }
format.json { render :json => {} }
end
end
def newproject
#projects = Project.all
end
end
Todos_form.html.erb
<%= form_for(#todo) do |f| %>
<% if #todo.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#todo.errors.count, "error") %> prohibited this todo from being saved:</h2>
<ul>
<% #todo.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
projects_form.html.erb
<%= form_for(#project) do |f| %>
<% if #project.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#project.errors.count, "error") %> prohibited this project from being saved:</h2>
<ul>
<% #project.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_area :name %>
</div>
<div class="field">
<%= f.label :project_id %><br />
<%= f.number_field :project_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
project.rb
class Project < ActiveRecord::Base
attr_accessible :name, :project_id
has_many :todos
def as_json(options = {})
super(options.merge(:only => [ :id, :name, :project_id]))
end
end
todo.rb
class Todo < ActiveRecord::Base
attr_accessible :content, :order, :done
belongs_to :project
def as_json(options = {})
super(options.merge(:only => [ :id, :content, :order, :done ]))
end
end
Hi I have two models Todos and Projects, in Todos index i want to show projects field values. How it is possible help me how to proceed it.
And i need Associations also.
Note: The field values must be comes from project controller and save it Database.
First project model should not have project_id column. project_id should be present in the todo model.
Then change your routes.
resources :projects do
resources :todos
end
Now add the code to project controller.
class ProjectsController < ApplicationController
def index
#projects = Project.all
end
def show
#project = Project.find(params[:id])
#todos = #project.todos.all
end
def new
#project = Project.mew
end
def create
#project = Project.new(params[:project])
if #project.save
.....
else
....
end
end
end
Individual project contains its own todos. So that in project show page you can display all the todos associated with the project.
Now the todo controller should be look like:
class TodosController < ApplicationController
def new
#project = Project.find(params[:project_id])
#todo = #project.todos.new
end
def create
#project = Project.find(params[:project_id])
#todo = #project.todos.build(params[:todo])
if #todo.save
.....
else
....
end
end
def show
#project = Project.find(params[:project_id])
#todo = #project.todos.find(params[:id])
end
end
Finally in app/views/projects/new.html.erb file add the following code:
<%= form_for #project do |f| %>
<% if #project.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#project.errors.count, "error") %> prohibited this project from being saved:</h2>
<ul>
<% #project.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_area :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And in app/views/todos/new.html.erb add the code:
<%= form_for #todo, url: project_todos_path(#project), method: :post do |f| %>
<% if #todo.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#todo.errors.count, "error") %> prohibited this todo from being saved:</h2>
<ul>
<% #todo.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>

How to Cancel Paypal Subscription?

I finally figured out how to implement PayPal Recurring Billing using this tutorial. http://railscasts.com/episodes/289-paypal-recurring-billing
Everything works, But how does one cancel the subscription....
Below is all of the code I've written, and I've also added some comments/questions
ERROR
app/controllers/subscriptions_controller.rb:27:in `show'
Couldn't find Subscription with id=cancel_account
Please help new to rails. :)
CONTROLLER
class SubscriptionsController < ApplicationController
def new
plan = Plan.find(params[:plan_id])
#subscription = plan.subscriptions.build
#subscription.user_id = current_user.id
if params[:PayerID]
#subscription.paypal_customer_token = params[:PayerID]
#subscription.paypal_payment_token = params[:token]
#subscription.email = #subscription.paypal.checkout_details.email
end
end
def create
#subscription = Subscription.new(params[:subscription])
if #subscription.save_with_payment
redirect_to #subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
def destroy
#subscription = current_user.subscription
#previous_plan = #subscription.plan
if #subscription.cancel_recurring
flash[:success] = 'Subscription Canceled.'
end
redirect_to some_path
end
def paypal_checkout
plan = Plan.find(params[:plan_id])
subscription = plan.subscriptions.build
redirect_to subscription.paypal.checkout_url(
return_url: new_subscription_url(:plan_id => plan.id),
cancel_url: root_url
)
end
end
MODELS
class Subscription < ActiveRecord::Base
attr_accessible :paypal_customer_token, :paypal_recurring_profile_token,
:plan_id, :user_id, :email, :paypal_payment_token
attr_accessor :paypal_payment_token
belongs_to :plan
belongs_to :user
validates_presence_of :plan_id
validates_presence_of :email
validates_presence_of :user_id
def save_with_payment
if valid?
if paypal_payment_token.present?
save_with_paypal_payment
end
end
def paypal
PaypalPayment.new(self)
end
def save_with_paypal_payment
response = paypal.make_recurring
self.paypal_recurring_profile_token = response.profile_id
save!
end
def payment_provided?
paypal_payment_token.present?
end
end
class PaypalPayment
def initialize(subscription)
#subscription = subscription
end
def checkout_details
process :checkout_details
end
def checkout_url(options)
process(:checkout, options).checkout_url
end
def make_recurring
process :request_payment
process :create_recurring_profile, period: :monthly, frequency: 1,
start_at: Time.zone.now + 1.month
end
def cancel_recurring
response = ppr.cancel_subscription(at_date_end: true) #Needs a end period field in
self.current_date_end_at = Time.at(response.current_date_end)
self.plan_id = plan.id
self.status = "canceled"
return self.save
end
private
def process(action, options = {})
options = options.reverse_merge(
token: #subscription.paypal_payment_token,
payer_id: #subscription.paypal_customer_token,
description: #subscription.plan.name,
amount: #subscription.plan.price.to_i,
currency: "USD"
)
response = PayPal::Recurring.new(options).send(action)
raise response.errors.inspect if response.errors.present?
response
end
end
VIEWS
<%= form_for #subscription do |f| %>
<%= f.hidden_field :plan_id %>
<%= f.hidden_field :user_id %>
<%= f.hidden_field :paypal_customer_token %>
<%= f.hidden_field :paypal_payment_token %>
<% unless #subscription.payment_provided? %>
<div class="field">
<%= radio_button_tag :pay_with, :paypal %>
<%= label_tag :pay_with_paypal do %>
<%= image_tag "paypal.png" %>
<% end %>
</div>
<% end %>
*** WHAT WOULD BE THE LINK TO CANCEL THE SUBSCRIPTION ***
<%= link_to image_tag("https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"),
paypal_checkout_path(plan_id: #subscription.plan_id) %>
<%= link_to "Cancel Subscription", cancel_account_subscriptions_path(plan_id:
#subscription.plan_id) %>
<div id="billing_fields">
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<% if #subscription.payment_provided? %>
Payment has been provided. Click "Subscribe" to complete the subscription.
<% end %>
<div class="actions">
<%= f.submit "Subscribe" %>
</div>
</div>
<% end %>
ROUTES
App::Application.routes.draw do
resources :subscriptions do
collection do
delete :cancel_account
end
end
get 'paypal/checkout', to: 'subscriptions#paypal_checkout'
end
To destroy a users paypal subscription you should create a destroy action in your subscription model.
Subscription_controller.rb
def destroy
#subscription = current_user.subscription
#previous_plan = #subscription.plan
if #subscription.cancel_recurring
flash[:success] = 'Subscription Canceled.'
end
redirect_to some_path
end
In your model get the current user and cancel their subscription. If the user is subscribed monthly but canceled within 2days out of the 30 days, their account subscription should be valid until the at_end_date period(just a heads up).
def cancel_recurring
response = ppr.cancel_subscription(at_date_end: true) #Needs a end period field in
self.current_date_end_at = Time.at(response.current_date_end)
self.plan_id = plan.id
self.status = "canceled"
return self.save
end
Routes.rb
resources :subscriptions do
collection do
delete :cancel_account
end
end
In your view you would iterate through the plans like so
<% #plans.each do |plan| %>
<%= link_to "Cancel Account", cancel_account_subscriptions_path(#subscription, plan_id: plan.id), method: :delete %>
<% end %>

Create method not submitting POST request

I have a controller in a rails app whereby a user can create a holiday request, it seems that when I fill out the necessary information it is not doing the POST request and submitting my form. My output in the RailsPanel follows: Rails Panel. From this its as if it is doing the GET request when surely on it should do a GET then a POST. I believe I have messed up somewhere around my create method. Any feedback would be great thank you!
controller
class HolidaysController < ApplicationController
before_filter :authenticate_user!
before_filter :admin_user, :only => [:index, :update, :edit, :absence]
before_filter :correct_user, :only => [:delete]
def new
#holiday = Holiday.new
#user = current_user
end
def show
#holiday = Holiday.find(params[:id])
c_u = current_user
end
def create
#user = current_user
#holiday = current.holidays.build(params[:holiday])
#holiday.approver_id = approval_method(current_user, #holiday)
if #holiday.save
redirect_to root_path
flash[:success]= "holiday application sent!"
else
render :new
end
end
def myholidays
#holidays = current_user.holidays.all
end
def index
#holidays = Holiday.all
end
def absence
#show the holidays where the approver id matches the current user id
#and state = "requested"'
#user = current_user
if current_user.role? :administrator
# a admin can view all current holiday requests
#holidays = Holiday.all( :conditions => 'state = "requested"')
else
#otherwise an admin sees the holiday requests that they are approvers for
#holidays = Holiday.all(:conditions => ["approver_id = #{current_user.id}", "state = requested"])
end
end
def edit
today = Date.today
#holidays = Holiday.all
#month = (params[:month] || (Time.zone || Time).now.month).to_i
#year = (params[:year] || (Time.zone || Time).now.year).to_i
#shown_month = Date.civil(#year, #month)
#L51 - Parses the given representation of date and time with the given template
#and returns a hash of parsed elements.
#holiday = Holiday.find(params[:id])
end
def update
admin = User.find(current_user.role? :administrator)
holiday = Holiday.find(params[:id])
user = User.find(id = holiday.user_id)
if holiday.update_attributes(params[:holiday])
if holiday.state == "approved"
user.absentdays = user.absentdays - (holiday.days_used).to_i
user.save
end
redirect_to absence_path, :notice => "Request updated"
else
render 'edit'
end
end
def destroy
Holiday.find(params[:id]).destroy
redirect_to root_url, :notice => "Request deleted"
end
private
def current_user?(user)
user == current_user
end
def admin_user
redirect_to dashboard_path, :notice => "You must be an admin to do this!" unless current_user.role? :administrator
end
def signed_in_user
redirect_to login_path, notice: "Please sign in." unless signed_in?
end
def correct_user
#user = current_user
redirect_to dashboard, notice: "You are not the correct user." unless current_user?(#user) or current_user.role? :administrator
end
def approval_method(current_user, holiday_to_approve)
found = false
days = holiday_to_approve.days_used
user = current_user
approver = user.role? :administrator
until found == true
#Admins should be automatically approved and have no approvers
if approver == nil
holiday_to_approve.state = "approved"
#if user absent days is equal to absent days - day and convert to integer
user.absentdays = user.absentdays - (days).to_i
user.save
found = true
else
redirect_to dashboard_path, :notice => "Request complete"
end
break if found == true
end
end
end
holidays/show.html.erb
<form class="form">
<p>You have<b><%= #user.absentdays %> days of holiday left.</b></p>
<%= form_for #holiday do |f| %>
<% if #holiday.errors.any? %>
<div>
<h2>Form is invalid</h2>
<ul>
<% for message in #holiday.error.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
Select the dates required for absence<br>
Start: <%= datepicker_input "holiday", "start_at", :minDate => 0, :dateFormat => "yy-mm-dd" %><br>
End: <%= datepicker_input "holiday", "end_at", :minDate => 0, :dateFormat => "yy-mm-dd" %>
<br><br>
Please select the type of absence you require<br>
<%= f.collection_select :type_id, Type.all, :id, :name, :prompt => "Select absence type" %>
<br><br>
<%= f.text_field :description %>
<br><br>
<%= f.submit "Submit Request", :class => "submit" %>
<% end %>
</form>
new.html.erb
<% provide(:title, 'apply for absence') %>
<p>You have <b><%= #user.absentdays %></b> days of holiday time left.</p>
<%= form_for #holiday do |f| %>
<% if #holiday.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #holiday.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
Select the dates required for absence<br>
start: <%= datepicker_input "holiday","start_at", :minDate => 0, :dateFormat => "yy-mm-dd" %><br>
end: <%= datepicker_input "holiday","end_at", :minDate => 0, :dateFormat => "yy-mm-dd" %>
<br><br>
Please select the type of absence you require<br>
<%= f.collection_select :type_id, Type.all, :id, :name, :prompt => "Select absence type" %>
<br><br>
Please provide a short description of the nature of your absence (if applicable)<br>
<%= f.text_field :description %>
<br><br>
<%= f.submit "submit" %>
<% end %>
</div>
The reason is, you are having a form in your holidays/show.html.erb but not in your holidays/new.html.erb.
According to rails convention, if form is submitted in new.html.erb, then by default the POST method is called of that particular controller.
But since your file is show.html.erb, you have to explicitly define your POST method in the form_for.
form_for #holiday , :url => { :action => :create }, :html => { :method => "post"} do |f|

Resources