Modal Form not working correctly - ruby-on-rails

My modal is working ( means when i click button it appears) but the form is not appearing, i have this modal in the index action so i have added <% #entries.each do |entry| %> and without it i am having undefined methodmodel_name' for NilClass:Class, any suggestions ?
<%= link_to "Assign", "#saturday-one", :class => "btn btn-primary", "data-toggle" => "modal" %>
<div class="modal hide fade" id="saturday-one">
<div class="modal-header">
<h3 id="myModalLabel">Time Table</h3>
</div>
<div class="modal-body">
<% #entries.each do |entry| %>
<%= simple_form_for(entry) do |f| %>
<%= f.association :subject, as: :select, label: 'Select Subject' %>
<%= f.association :employee, as: :select, label: 'Assign Employee' %>
<%= f.submit %>
<% end %>
<% end %>
</div>
<div class="modal-footer">
<button aria-hidden="true" class="btn btn-info" data-dismiss="modal">Done</button>
</div>
</div>
time_table_entries_controller.rb
class TimeTableEntriesController < ApplicationController
def index
#entries = TimeTableEntry.all
end
def show
#entry = TimeTableEntry.find(params[:id])
end
def new
#entry = TimeTableEntry.new
end
def create
#entry = TimeTableEntry.new(params[:time_table])
if #entry.save
redirect_to time_table_entries_url , notice: 'Time table Entries saved'
else
render :new
end
end
def edit
#entry = TimeTableEntry.find(params[:id])
end
def update
#entry = TimeTableEntry.find(params[:id])
if #entry.update_attributes(params[:time_table])
redirect_to time_table_entries_url, notice: 'TimeTableEntry Updated.'
else
render :edit
end
end
end

Related

Ruby on Rails form error not giving any output/ not working

Hello guys I searched everywhere on how to output form errors but no luck. I tried almost all the code I found on the internet but still didn't work.
Here are some of my files:
view/books/new.html.erb
<div class="container">
<h2>Create a new book</h2>
<%= form_with model: #book, url: create_new_book_path do |f| %>
<% if #book.errors.any? %>
<ul>
<% #book.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<div class="form-group row">
<%= label_tag(:title, "Title:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.text_field :title, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= label_tag(:price, "Price:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.text_field :price, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= label_tag(:subject_id, "Subject:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.collection_select :subject_id, #subjects, :id, :name, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= label_tag(:description, "Book description:", class: "col-sm-2 col-form-label") %>
<div class="col-sm-10">
<%= f.text_area :description, class: "form-control" %>
</div>
</div>
<%= submit_tag "Create book", class: "btn btn-success" %>
<%= link_to "Cancel", books_path, class: "btn btn-danger" %>
<% end %>
<br/>
</div>
books_controller.rb
class BooksController < ApplicationController
def index
#books = Book.all
end
def show
#book = Book.find(params[:id])
end
def new
#book = Book.new
#subjects = Subject.all
end
def create
#book = Book.new(book_params)
end
def book_params
params.require(:book).permit(:title, :price, :subject_id, :description)
end
def edit
#book = Book.find(params[:id])
#subjects = Subject.all
end
def update
#book = Book.find(params[:id])
if #book.update_attributes(book_params)
redirect_to action: "index"
else
#subjects = Subject.all
render action: "edit"
end
end
def destroy
Book.find(params[:id]).destroy
redirect_to action: "index"
end
end
routes.rb
get 'books/new', to: 'books#new', as: 'new_book'
post 'books/create', to: 'books#create', as: 'create_new_book'
view/layouts/application.html.erb
<main role="main">
<%= yield %>
</main>
I don't really know what I'm missing to get the errors, grateful for your answers!!
try putting them in a flash like this and render it in your view
def create
#book = Book.new
if #book.update(book_params)
flash[:notice] = 'success'
redirect_to action: 'index'
else
flash[:alert] = #book.errors.full_messages.join(', ')
redirect_to action: 'index'
end
end
and in your view render those flashes like
<% if flash[:notice]%>
<span class='notice'><%= flash[:notice] %></span>
<% end %>
<% if flash[:alert]%>
<span class='alert'><%= flash[:alert] %></span>
<% end %>

AJAX not working in Rails same-page update

I am trying to build a Q&A app with Ajax on the Index.html.erb. I manage to get the form remotely loading, but when saving the records, the AJAX does not work and the user is taken to the normal show.html.erb. Apart from the Ajax not kicking off, everything works well.
My code is as below:
index.html.erb (Contain a partial for input, and a partial for results)
<div>
<h3 class="section_title"> Q&A </h3>
<hr>
<div id="qanda-form" style="display:none;"> </div>
</div>
<div id="qandas">
<%= render 'qandas/qanda' %>
</div>
_qanda.html.erb (is the partial for results)
<% #qandas.each do |my_qanda| %>
<div class="col-md-9">
<div>
Created <%= local_time(my_qanda.created_at) %>, by <%= User.find_by(id: my_qanda.user_id).full_name %>
</div>
</div>
<% end %>
_form.html.erb (is the input form - has nested form via Cocoon)
<%= simple_form_for #qanda, remote: true do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<div class="col-md-12 form-inputs">
<div class="col-md-8">
<%= f.input :title, label: 'Q&A Title:' %>
</div>
</div>
<div class="qandasquestions">
<%= f.simple_fields_for :qandasquestions do |builder| %>
<% render 'qandas/qandasquestion_fields', f: builder %>
<% end %>
<div class="links btn-group" style="min-height: 34px !important">
<%= f.button :submit, "Publish Q&A", class: "btn btn-default" %>
<%= link_to_add_association 'Add Question', f, :qandasquestions, class: 'btn btn-default', data: {association_insertion_node: '.qandasquestions', association_insertion_method: :append} %>
<%= link_to 'Back', qandas_path, class: "btn btn-default" %>
<%= f.input :company, :as => :hidden, :input_html => {:value => current_user.company} %>
</div>
</div>
<% end %>
Controller:
def index
#qandas = Qanda.all
respond_to do |format|
#qandas = Qanda.all
format.html
format.json
end
end
def create
#qanda = current_user.qandas.build(qanda_params)
respond_to do |format|
if #qanda.save!
#qandas = Qanda.all
format.html { redirect_to #qanda, notice: 'Qanda was successfully created.' }
format.json {render :layout => false}
else
format.html { render :new }
format.json { render json: #qanda.errors, status: :unprocessable_entity }
end
end
end
create.js.erb
$('#qandas').html("<%= j render partial: 'qandas/qanda' %>");
$('#qanda-form').slideUp(350);
new.js.erb
$('#qanda-form').html("<%= j render 'qandas/form' %>");
$('#qanda-form').slideDown(350);
Anybody can see why the Ajax does not kick off please? why am I redirected to the traditional SHOW page please?
Try updating your code to this and let me know if it's working?
def create
#qanda = current_user.qandas.build(qanda_params)
if #qanda.save!
#qandas = Qanda.all
else
#errors = #qanda.errors
end
end

Getting Argument Error when trying to call form of other controller in another controller show page

i am having 2 models where invoice_details has_many multiple_goods and multiple_goods belongs_to invoice_details.
I am having a condition where when I click on new I have to show the form of multiple_goods as a pop-up in invoice_details_show.
invoice_details/show.html.erb:
<div><%= link_to 'New Person', '#new_person_modal', 'data-toggle' => 'modal' %></div>
<%# Bootstrap modal markup. #see: http://getbootstrap.com/javascript/#modals %>
<div class="modal fade" id="new_person_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Create new person</h4>
</div>
<div class="modal-body">
<%# Render the new person form (passing modal => true to enable remote => true) %>
<%= render 'multiple_goods/form', modal: true %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
multiple_goods/_form.html.erb:
<%=form_for([:invoice_detail,#multiple_good], html: {class: 'form-horizontal', role: 'form' }) do |f| %>
<% if #multiple_good.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#multiple_good.errors.count, "error") %> prohibited this multiple_good from being saved:</h2>
<ul>
<% #multiple_good.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<br/>
<div class="field">
<%= f.label :description_of_goods1, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :description_of_goods1, :class => 'text_field', :required => true,:maxlength => 20, :placeholder => '20 Alpha numeric characters' %>
</div>
</div>
<div class="field">
<%= f.label :quatity1, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :quatity1, :class => 'text_field', :required => true,:maxlength => 20, :placeholder => 'Enter quatity' %>
</div>
</div>
<div class="field">
<%= f.label :price_per_unit1, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :price_per_unit1, :class => 'text_field', :placeholder => 'Enter price Per unit' %>
</div>
</div>
<div class="field">
<%= f.label :total_amount1, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :total_amount1, :class => 'text_field', readonly: true, :placeholder => 'This field is auto saved' %>
</div>
</div>
<div class="form-actions2"style="text-align:center">
<%= f.submit :class => 'btn btn-primary' %>
</div>
</div>
<% end %>
Finally my controller:
class MultipleGoodsController < ApplicationController
before_action :set_multiple_good, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#multiple_goods = MultipleGood.all
respond_with(#multiple_goods)
end
def show
respond_with(#multiple_good)
end
def new
#multiple_good = MultipleGood.new
respond_with(#multiple_good)
end
def edit
end
def create
#invoice_detail = InvoiceDetail.find(params[:invoice_detail_id])
#multiple_good = #invoice_detail.multiple_goods.create(multiple_good_params)
redirect_to invoice_detail_path(#invoice_detail)
end
def update
#multiple_good.update(multiple_good_params)
respond_with(#multiple_good)
end
def destroy
#multiple_good.destroy
respond_with(#multiple_good)
end
private
def set_multiple_good
#multiple_good = MultipleGood.find(params[:id])
end
def multiple_good_params
params.require(:multiple_good).permit(:description_of_goods1, :quatity1, :price_per_unit1, :total_amount1)
end
end
My invoice Details controller
class InvoiceDetailsController < ApplicationController
before_action :set_invoice_detail, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#invoice_details = InvoiceDetail.all
respond_with(#invoice_details)
end
def show
#invoice_detail = InvoiceDetail.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #invoice_detail }
format.pdf { render :layout => false }
end
end
def new
#invoice_detail = InvoiceDetail.new
#invoice_detail_attachment = #invoice_detail.invoice_detail_attachments.build
end
def edit
end
def create
#invoice_detail = InvoiceDetail.new(invoice_detail_params)
respond_to do |format|
if #invoice_detail.save
params[:invoice_detail_attachments]['avatar'].each do |a|
#invoice_detail_attachment = #invoice_detail.invoice_detail_attachments.create!(:avatar => a, :invoice_detail_id => #invoice_detail.id)
end
format.html { redirect_to #invoice_detail, notice: '' }
else
format.html { render action: 'new' }
end
end
end
def update
#invoice_detail.update(invoice_detail_params)
if #invoice_detail.save
params[:invoice_detail_attachments]['avatar'].each do |a|
#invoice_detail_attachment = #invoice_detail.invoice_detail_attachments.create!(:avatar => a, :invoice_detail_id => #invoice_detail.id)
end
redirect_to invoice_details_path
end
end
def destroy
#invoice_detail.destroy
redirect_to invoice_details_path
end
def download
require 'zip/zip'
require 'zip/zipfilesystem'
#invoice_detail = InvoiceDetail.find(params[:invoice_id])
t = Tempfile.new('tmp-zip-' + request.remote_ip)
Zip::ZipOutputStream.open(t.path) do |zos|
#invoice_detail.invoice_detail_attachments.each do |file|
zos.put_next_entry(file.invoice_detail)
zos.print IO.read(file.avatar.path)
end
end
send_file t.path, :type => "application/zip", :filename => "#{#invoice_detail.invoice_number}.zip"
t.close
end
private
def set_invoice_detail
#invoice_detail = InvoiceDetail.find(params[:id])
end
def invoice_detail_params
params.require(:invoice_detail).permit(:avatar,:attachment,:invoice_number, :supplier_name, :invoice_date, :invoice_due_date, :description_of_goods, :quatity, :price_per_unit, :total_amount, :mode_of_payment, :status, :shipping_country, :sl_no, :containers, :net_weight, :bl_number, :bl_date, :insurance_provider, :insurance_amount, :insurance_status, :coo_payment, :farworder, :farworder_inv_amt_doller, :farworder_inv_amt_idr, :payment_status_to_farworder,:final_amount )
end
end
When I am running on server, i am getting error as :
ArgumentError in InvoiceDetails#show
First argument in form cannot contain nil or be empty
Your action show in InvoiceDetailsController doesn't include a new multiple_goods for the _form, you should take into account that render in views only render a view doesn't pass throught another action.
def show
#invoice_detail = InvoiceDetail.find(params[:id])
#multiple_good = MultipleGood.new
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #invoice_detail }
format.pdf { render :layout => false }
end
end

How to use partials with more than one collection in rails

I want to use two collection #ad_item and #user in my partial. Here is my index erb...
<% if #ad_items.any? && #user.any? %>
<%= render partial: 'yourads/ad_item', collection: {#ad_items,#user} %>
<% end %>
and here is my controller ...
def index
#ad_items = Yourad.all
#user = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #yourads }
end
end
and here is my _ad_item.erb.html partial
<span class="date"><%= ad_item.created_at.to_date() %></span>
<span class="location"><%= ad_item.title %></span>
<div style="float:left"><%= ad_pic #user,ad_item %></div>
<div class="description"><%= ad_item.description %></div>
My helper function is ..
def ad_pic(user,ad)
cl_image_tag("Ad#{user.id}#{ad.id}.jpg", :version => rand(1000000000), :alt => "Ad pic",:width => 70, :height => 70, :crop => :fill)
end
it gives syntax error in ..
<%= render partial: 'yourads/ad_item', collection: {#ad_items,#user} %>
<%= render partial: 'yourads/ad_item', collection: #ad_items ,
locals: {users: #users} %>
and in view
<% for user in users %>
<span class="date"><%= ad_item.created_at.to_date() %></span>
<span class="location"><%= ad_item.title %></span>
<div style="float:left"><%= ad_pic user,ad_item %></div>
<div class="description"><%= ad_item.description %></div>
<% end %>
see Passing Local Variables
<%= render partial: 'yourads/ad_item', :locals => {:ad_items=>#ad_items,:user => #user }%>
you can access #ad_items as ad_items and #user as user in your yourads/ad_item partial

Method becomes nil after an ajax response?

The following code does the following: If the user, voted up show him a delete vote form and a vote down form. If the user voted down, show him a vote up form and the delete vote form. Otherwise just show the vote up and vote down form (I omitted some of the code so the question doesn't get too long).
(scenario: user voted down):
posts_controller.rb:
def show
#post = Post.find(params[:id])
#replies = #post.replies.paginate(page: params[:page])
#reply = #post.replies.build
#vote = Vote.new
store_location
end
votes_controller.rb:
class VotesController < ApplicationController
before_filter :signed_in_user
def create
#votable = find_votable
# Destroy the vote first in case the user already voted
if already_voted?
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
end
#vote = #votable.votes.build(params[:vote])
#vote.user_id = current_user.id
#votable.save
respond_to do |format|
format.html { redirect_back }
format.js
end
end
def destroy
#votable = find_votable
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
#votable.reload
respond_to do |format|
format.html { redirect_back }
format.js
end
end
private
def find_votable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def already_voted?
#votable.votes.exists?(:user_id => current_user.id)
end
end
posts/vote_form
<div class="vote-form">
<% if #post.votes.exists?(:user_id => current_user.id) %>
<% if #post.votes.find_by_user_id(current_user.id).polarity == -1 %>
<%= form_for ([#post, #vote]), remote: true do |f| %>
<%= f.hidden_field :polarity, value: 1 %>
<div class="form-actions">
<%= button_tag type: :submit, class: "btn btn-small vote" do %>
<i class="icon-thumbs-down"></i> Vote up
<% end %>
</div>
<% end %>
<%= form_for ([#post, #post.votes.find_by_user_id(current_user.id)]),
method: :delete,
remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "btn btn-small btn-primary unvote" do %>
<i class="icon-thumbs-up"></i> Vote down
<% end %>
</div>
<% end %>
<% end %>
votes/create.js:
$('#<%= #votable.class.name.downcase %>-<%= #votable.id %> .vote-form').html(
"<%= escape_javascript(render('shared/delete_vote')) %>"
);
shared/_delete_vote.html.erb:
<% if #votable.votes.find_by_user_id(current_user.id).polarity == -1 %>
<%= form_for ([#votable, #votable.votes.new]), remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "vote-down btn btn-small" do %>
<i class="icon-thumbs-up"></i> Vote up
<% end %>
</div>
<% end %>
<%= form_for ([#votable, #vote]), method: :delete, remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "vote-up btn btn-small btn-primary" do %>
<i class="icon-thumbs-up"></i> Vote down
<% end %>
</div>
<% end %>
<% end %>
So, now everything works fine, except that I get this error when I click vote down, and then vote up right after (without refreshing the page):
ActionView::Template::Error (undefined method `polarity' for nil:NilClass):
1: <% if #votable.votes.find_by_user_id(current_user.id).polarity == 1 %>
2: <%= form_for ([#votable, #vote]), method: :delete, remote: true do |f| %>
What could be the problem?
EDIT:
I realized that the line in the error message is the problem (not #votable):
<% if #votable.votes.find_by_user_id(current_user.id).polarity == 1 %>
Strange, I thought it was the same as
<% if #post.votes.find_by_user_id(current_user.id).polarity == 1 %>
I think the problem is here:
def destroy
#votable = find_votable
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
#votable.reload
respond_to do |format|
format.html { redirect_back }
format.js
end
end
You destroy the vote for current user, so it can not be found inside view:
#votable.votes.find_by_user_id(current_user.id).polarity
That's why polarity is called on nil. You should reword the logic of your vote manipulations.
EDIT:
As the easiest solution, you may replace
if #votable.votes.find_by_user_id(current_user.id).polarity == -1
with
if #votable.votes.find_by_user_id(current_user.id).blank?

Resources