rails 5.1: pass variable to partial through ajax - ruby-on-rails

I'm new to rails and experimenting. After I managed to do this, I was now trying to do the following:
when clicking on a link for a setting's name, it's description should be rendered in a partial on the same page. I managed to render the partial, but only if I put some static text in it. For some reason I'm not able to pass the #fbs variable and thus to select the descriptions. I tried many different suggestions on other similar questions but I really don't get how I should do it. I'm using ruby 2.4.0 and rails 5.1
Here is my _settingsfb.html.erb (which is a partial of index.html.erb and which contains the Link_to)
<div class="container fluid">
<div class="row">
<!-- settings links -->
<div class="col-md-4 ">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Settings</h3>
</div>
<div class="panel-body">
<% #fbs.each do |fbs| %>
<ul>
<li> <%= link_to fbs.name, controller: 'settingsfb', action: 'show', id: fbs.id,remote: true %></li>
</ul><% end %>
</div>
</div>
</div>
<!-- setting description -->
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Description</h3>
</div>
<div class="panel-body">
<div id="desc">
<!-- here goes the description partial -->
</div>
</div>
</div>
</div>
here the settingsfb_controller (the relevant part)
class SettingsfbController < ApplicationController
before_action :set_setting, only: [:show, :edit, :update, :destroy]
# GET /settings
# GET /settings.json
def index
#settings = Setting.all
#fbs = Setting.where("Sns = 1")
end
# GET /settings/1
# GET /settings/1.json
def show
respond_to do |format|
format.js {render layout: false}
end
end
the show.js.erb
$("#desc").html("<%= j render 'settingsfb/show' %>");
and the _show partial
<%= #fbs.name %>
this is what I get when I click on a the link
Started GET "/settingsfb/show?id=1" for 127.0.0.1 at 2017-05-14 17:08:34 +0200
Processing by SettingsfbController#show as JS
Parameters: {"id"=>"1"}
Setting Load (0.3ms) SELECT "settings".* FROM "settings" WHERE "settings"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Rendering settingsfb/show.js.erb
Rendered settingsfb/_show.html.erb (2.6ms)
Rendered settingsfb/show.js.erb (3.8ms)
Completed 500 Internal Server Error in 6ms (ActiveRecord: 0.3ms)
ActionView::Template::Error (undefined method `name' for nil:NilClass):
1: <%= #fbs.name %>
app/views/settingsfb/_show.html.erb:1:in `_app_views_settingsfb__show_html_erb___617047289144576595_70310163068960'
app/views/settingsfb/show.js.erb:1:in `_app_views_settingsfb_show_js_erb___3755597588635490219_70310163079560'
app/controllers/settingsfb_controller.rb:17:in `block (2 levels) in show'
app/controllers/settingsfb_controller.rb:16:in `show'
any Ideas?

You should initialize #fbs before rendering after show action. So add #fbs = Setting.find(params[:id]) at the beginning of the show method.

The error indicates there is no #fbs variable. You're calling the settingsFbShow partial from the show.js.erb view but not passing any variables. Try
$("#desc").html("<%= j render 'settingsfb/show', locals: {fbs: fbs} %>");
Then in create.js.erb
<%= fbs.name %>

Related

Form_with, using a range, output pdf, get instead of post Ruby on Rails

My users can add in inventory and then print all the inventory out into lables using a pdf. This part works, now I need to create a form to get the range for items to be printed. The params come over and the all my variables are correct when I check them with byebug.
First issue is that my form wants to post instead of get
No route matches [POST] "/excute_print_tags.pdf"
Now if I add the Route the code runs and no output and I get this in the command line
Inventory Load (0.4ms) SELECT "inventories".* FROM "inventories" WHERE "inventories"."user_id" = $1 AND "inventories"."print_ref" >= $2 AND "inventories"."print_ref" < $3 [["user_id", 1], ["print_ref", 4], ["print_ref", 7]]
↳ app/pdfs/inventory_landscape_pdf.rb:18:in `inventory_number'
Rendering text template
Rendered text template (Duration: 0.0ms | Allocations: 2)
Sent data Westcoast Board and Ski_myskiswapinvenotry2020-08-05 14:51:40 -0700.pdf (0.9ms)
Completed 200 OK in 65227ms (Views: 0.6ms | ActiveRecord: 8.6ms | Allocations: 220205)
form code inside views/inventories/print_tags.html.erb
<%= form_with url: excute_print_tags_path(format: "pdf") do |form| %>
<div class="flex flex-wrap -mx-3 mb-2">
<div class="w-full md:w-1/3 px-3 mb-6 md:mb-0">
<div class="form-group">
<%= form.label :print_ref1 %>
<%= form.number_field :print_ref1, class: "form-control" %>
</div>
</div>
<div class="w-full md:w-1/3 px-3 mb-6 md:mb-0">
<div class="form-group">
<%= form.label :print_ref2 %>
<%= form.number_field :print_ref2, class: "form-control" %>
</div>
</div>
<div class="w-full md:w-1/3 px-3 md:mb-0 mt-8 ">
<div class="form-group">
<%= form.button class: "btn btn-primary" %>
</div>
</div>
</div>
<% end %>
Then inside the controllers/inventories_contoller
def excute_print_tags
#print_ref1 = params[:print_ref1]
#print_ref2 = params[:print_ref2]
#filtered_inventory = #user_inventory.where(print_ref: #print_ref1...#print_ref2)
byebug
respond_to do |format|
format.html
format.pdf do
pdf = InventoryLandscapePdf.new(#filtered_inventory)
send_data pdf.render, filename: "#{current_user.company}_myskiswapinvenotry#{Time.new}.pdf",
type: "application/pdf",
disposition: "inline"
end
end
end
I have also tried adding the above code to print_tags section of the inventories and calling to itself. Same problem ... I think it has something to do with the way my forms is and it is only allowing it to be sent as a post instead of a get, technically its just a search right? I did try a search for that I found but that didnt solve this issue either. Any help is appreciated.
I had to change this line
<%= form_with url: excute_print_tags_path(format: "pdf") do |form| %>
To this line
<%= form_with url: excute_print_tags_path(format: "pdf"), local: true, method: :get do |form| %>
Thanks Les for your help

Ruby on Rails full calendar gem ActionView::Template:Error

I've been working on a ruby on rails app and trying to integrate the full calender gem but am experiencing errors. I can get the calendar to display but not the module to display to enter new events, every time I fix an error I seem to run into another.
I'm currently getting an ActionView::Template::Error
In my console
Started GET "/entries/new?_=1492426544714" for ::1 at 2017-04-17 11:55:52 +0100
Processing by EntriesController#new as JS
Parameters: {"_"=>"1492426544714"}
Rendered entries/_form.html.erb (46.9ms)
Rendered entries/_new.html.erb (78.2ms)
Rendered entries/new.js.erb (109.6ms)
Completed 500 Internal Server Error in 141ms (ActiveRecord: 0.0ms)
ActionView::Template::Error (undefined method `entries_index_path' for #<#<Class:0x61746a8>:0x9f321c0>):
1: <%= simple_form_for #entry, remote: true do |f| %>
2: <div class="form-inputs">
3: <%= f.input :title %>
4: <%= f.input :date_range, input_html: { class: "form-control input-sm date-range-picker" } %>
app/views/entries/_form.html.erb:1:in `_app_views_entries__form_html_erb___640013074_85163292'
app/views/entries/_new.html.erb:9:in `_app_views_entries__new_html_erb__917401192_85193628'
app/views/entries/new.js.erb:1:in `_app_views_entries_new_js_erb__613427356_85255440'
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (0.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.6/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb (78.1ms)
new.js.erb
$('#remote_container').html('<%= j render "new" %>');
$('#new_entry').modal('show');
_new.html.erb
<div class="modal fade" id="new_entry">
<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">Create New Event</h4>
</div>
<div class="modal-body">
<%= render 'form', entry: #entry %>
</div>
</div>
</div>
</div>
any ideas?
It is a Rails magic, when you don't specify second option(url) for simple_form_for, Rails try to set it, in your case <%= simple_form_for #entry do |f|%> converts by Rails to <%= simple_form_for #entry, url: entries_index_path do |f|%>. In your routes, there is no such _path helper(as error says).
To resolve this issue run bundle rake routes and set the right url option.
Check the documentation

Call a method associated with partial rails

In my controller I have this method that retuns to me the list of specific books controller/books_controller
def postings
#books = Book.postings(current_user.id).order("created_at ASC")
render :partial =>'postings'
end
I have a partial in views/books/_postings.html.erb
<div class="container">
<h4>My Partial Postings</h4>
<% #books.each do |book| %>
<div class="row">
<div class="col-sm-2"><img src="<%= book.image_path %>" alt="..." class="img-responsive"/></div>
<div class="col-sm-10">
<h4 class="nomargin"><%= book.title %></h4>
<p><%= book.description %></p>
<p>Quantity: <%= book.quantity %></p>
<p>Available for: <%= book.sale_type %></p>
</div>
</div>
<hr>
<% end %>
</div>
In my routes :
resources :books do
collection do
get 'postings'
end
end
on running rake routes :
postings_books GET /books/postings(.:format) books#postings
When I use localhost:3000/books/postings I get the desired partial showing list of books .But when I want to call this partial from some other view eg from localhost:3000/dashboard/index:
<div class="tab-pane" id="postings">
<%= render 'books/postings', :collection => #books %>
</div>
I get the following error:
Showing /home/swati/867/WorkSpace2/assignment_3/app/views/books/_postings.html.erb where line #4 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #4):
<div class="container">
<h4>My Partial Postings</h4>
<% #books.each do |book| %>
<div class="row">
<div class="col-sm-2"><img src="<%= book.image_path %>" alt="..." class="img-responsive"/></div>
<div class="col-sm-10">
I understand that render is just rendering the partial without calling my method postings in books_controller and my partial has no access to #books , which is nil. How can aprroach this ?
When you access dashboard/index you are actually calling index method of dashboards_controller. If you would like to render the books/postings partial there, you need to add the list of books (#books) in that controller too.
More info here: http://guides.rubyonrails.org/action_controller_overview.html

Confused as to why I am getting a nil error on a new user form before it has been called

I will try my best to be clear, I myself am confused as to what is happening or how to explain it. I am building a Rails app.
I have two forms so far, both in modals, which are in partials.
I have my app rooted to a path called home, which is defined in application controller. In my html.erb, I want a particular styling on that page, so I have set it so that if I am on the home page, the body tag gets a class of 'homepage'. Here is the code from application_controller.rb:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
include SessionsHelper
def home
#home_page = true
# #user = User.new
end
end
As you can see, I have a code #user = User.new commented out. I added that because without it, Rails throws an error First argument in form cannot contain nil or be empty in reference to my signup form which in in a module, which is in a partial. Here is that form:
<div class="modal fade" id="loginModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h2 class="modal-title">Welcome Back!</h2>
</div>
<div class="modal-body">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= label_tag :username %>:
<%= f.text_field :user_name, class: 'form-control'%>
<br>
<%= label_tag :password%>:
<%= f.password_field :password, class: 'form-control'%>
<br><br>
<%= submit_tag "Login", class: 'login-button'%>
<% end %>
</div> <!-- modal body -->
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div> <!-- modal-content -->
</div> <!-- modal-dialog -->
</div> <!-- login-modal -->
If uncomment that line in the application controller, I can go to the home page without errors. But then it messes up sessions, because from what I can tell, I have some new user waiting to be created, as that line is invoking the form I suppose. In addition, from terminal, I can see it is also finding user 1 for some reason. Here is part of the terminal output if it helps:
Started GET "/" for ::1 at 2015-08-19 23:35:30 -0400
ActiveRecord::SchemaMigration Load (0.5ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by ApplicationController#home as HTML
Rendered application/home.html.erb within layouts/application (2.2ms)
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
Rendered users/_log_in_form.html.erb (14.2ms)
Rendered users/_new.html.erb (6.2ms)
Completed 500 Internal Server Error in 583ms (ActiveRecord: 6.2ms)
ArgumentError - First argument in form cannot contain nil or be empty:
actionview (4.2.3) lib/action_view/helpers/form_helper.rb:432:in `form_for'
app/views/users/_new.html.erb:15:in `_app_views_users__new_html_erb___2821927674300231403_70140243283980'
actionview (4.2.3) lib/action_view/template.rb:145:in `block in render'
so when I do log in, despite my user id being 1 in the database, it is being shown in terminal as 2 - which throws a bunch of undefined errors etc when I try to log my username or session[:user_id] in console(because ther IS no user 2). Of course, putting that #user = User.new line is wrong and I know this, but without it I get an error on the form as soon as I go to the home page, it seems to need to have the #user available...but with it there I get errors in sessions and cant log in or out properly...what is going on here? Here is the part of my application.html.erb that is rendering the forms, in case it helps. Also note that when I log in, I get no errors and the logout link appears, but I am unable to log out (more errors) and as I said, terminal shows me as having a id of 2 when it should be 1. I have the modal's render commented out for testing.
<% if logged_in? %>
<h1>Welcome back <%= current_user.user_name %>!</h1>
<%= link_to "Logout", sessions_path, method: :destroy %>
<% end %>
<ul>
<li> Find a Project</li>
<li lass="btn btn-info btn-lg" data-toggle="modal" data-target="#registerModal">Register</li>
<li lass="btn btn-info btn-lg" data-toggle="modal" data-target="#loginModal">Login</li>
</ul>
<div id='login-container'>
<!-- <%= render 'users/log_in_form' %> -->
</div>
<div class="signup-container">
<!-- <%= render 'users/new' %> -->
</div>
In your form do something like this:
<%= form_for(#user, url: :sessions_path) do |f| %>
and in yourApplicationController
def home
#home_page = true
#user = User.new
end
That is uncomment #user = User.new
See I will explain what is wrong with what you are doing. You didn't define the model object for the form_for method. The form_for method accepts 2 arguments and the 1st argument should be the model object like #user or #post etc. Please read more [here], (http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for), and you will completely understand how form_for is exactly used.

rails render partial after ajax get request

I use Jvectormap into my Rails 3 app.
When I click on it, I want to hide the map and visualize a partial with information about the selected country.
I handle the map click and I send a GET req to the server.
users.js.coffee.erb
$ ->
$("#world-map").vectorMap
onRegionClick: (event, code) ->
$('#world-map').hide(1000)
$.get('/users/statistics', {code: code});
$('#statistics').show(1000)
users_controller.rb
def statistics
#country = Country.find_by_two_letter_code((params[:code]).downcase)
render :nothing => true
end
this is the response
Started GET "/users/statistics?code=ET" for 127.0.0.1 at 2013-06-02 17:54:49 +0200
Processing by UsersController#statistics as /
Parameters: {"code"=>"ET"}
Country Load (0.2ms) SELECT "countries".* FROM "countries" WHERE
"countries"."two_letter_code" = 'et' LIMIT 1
Rendered text template (0.0ms)
Completed 200 OK in 2ms (Views: 0.6ms | ActiveRecord: 0.2ms)
and the view
show.html.erb
<p> <div id="world-map" style="width: 620px; height: 300px"></div>
<div id="statistics" style="width: 620px; height: 300px; display:none;">
<section>
<%= render partial:'statistics', :locals => {:country => #country} %>
</section>
</div>
</p>
_statistics.html.erb
<%= link_to '<i class="icon-remove"></i>'.html_safe%>
<%=country%>
<%=#country%>
Now, everything works, but the partial doesn't visualize the country value.
I don't undestand if I have to re-render the partial after the ajax get request, and how.
I've tried to change the controller in another way, but the behavior is the same.
def statistics
#country = Country.find_by_two_letter_code((params[:code]).downcase)
render 'users/_statistics'
end
i think that since you don't need a page refresh and just need to display the details the country, you can use ajax.
show.html
<p> <div id="world-map" style="width: 620px; height: 300px"></div>
<div id="statistics" style="width: 620px; height: 300px; display:none;">
<section>
<div id="place_partial_here"></div>
</section>
</div>
</p>
in the controller
def statistics
#country = Country.find_by_two_letter_code((params[:code]).downcase)
respond_to do |format|
format.js
end
end
in statistics.js.haml #i am comfortable with haml.
$('#place_partial_here').replaceWith("#{escape_javascript(render partial: 'country_data', locals: {country: #country})}");
in the _country.html.haml
#place_partial_here #id is denoted in haml using hash
= country.name #display country name
= country.code #display code
the partial must have the view code 'inside' the id 'place_partial_here' so that it can be used in further ajax calls
have you tried this
render :partial => "statistics", :collection => #country

Resources