Generate form for with csv format - ruby-on-rails

I am trying to use form for to specify two date fields, which specifies a timespan for data that I want to put inside a CSV file. I am able to create my csv file but I cant get rails to respond to csv format.
Here I have added my format: :csv in the form_for field, but it wont respond to that format in my controller.
<%= form_for(:estimation, html: {class: "estimations-form-horizontal"}, url: research_path, format: :csv, method: :get) do |f| %>
<div class="form-group-estimations">
<%= f.label :from_start_date, "Från och med" %>
<%= f.date_field :from_start_date, class: "form-control" %>
</div>
<div class="form-group-estimations">
<%= f.label :to_end_date, "Till och med" %>
<%= f.date_field :to_end_date, class: "form-control" %>
</div>
<%= f.submit "Hämta data", class: "btn btn-primary" %>
<% end %>
My controller, using format.csv ...
def research
if (params[:estimation] && params[:estimation][:from_start_date] && params[:estimation][:to_end_date])
start_date = params[:estimation][:from_start_date].to_date.beginning_of_day
end_date = params[:estimation][:to_end_date].to_date.end_of_day
if(start_date > end_date)
puts "Dates are in wrong order"
else
#estimations = Estimation.where(:created_at => start_date..end_date)
puts to_csv(#estimations)
respond_to do |format|
format.csv { send_data to_csv(#estimations), filename: "skattningar-#{Date.today}.csv" }
end
end
else
puts "Not enough data"
end
end

:url conflicts with :format If you are passing both :url and :format,
url overwrites the use of format, so you’ll need to pass it in the url
like so:
form_for user, :url => user_path(#user, :format => :json)
Source

Related

rails - multiple paths for a search form

I'm implementing the website. I got a problem for a search form. I upload my code, and what i want to ask is how to set the search 'path' through 'index' and 'historical' on homes_controller
Below, my code:
app/controllers/homes_controller
def index
#homes = Home.where(:category => 1).reverse
end
def historical
#homes = Home.where(:category => 2).reverse
end
app/views/layouts/application.html.erb
Below, this code is temporary code for now. I should change it.
<%= form_tag(homes_path, :method => 'get', id: "search-form" do %>
<%= text_field_tag :search, params[:search], placeholder: "검색" %>
<%= submit_tag "검색", :name => nil %>
<% end %>
Am not sure what you are supposed to do here
But as per the question - I can give a solution to your problem
Keep an instance variable in your controller actions - like this
app/controllers/homes_controller
def index
#homes = Home.where(:category => 1).reverse
#search_path = "path you want to give"
end
def historical
#homes = Home.where(:category => 2).reverse
#search_path = "path you want to give"
end
and in your layout you can use it like this
app/views/layouts/application.html.erb
<%= #search_path.present? %>
<%= form_tag(#search_path, :method => 'get', id: "search-form" do %>
<%= text_field_tag :search, params[:search], placeholder: "검색" %>
<%= submit_tag "검색", :name => nil %>
<% end %>
<% end %>

Using Rails model method to fetch and return value

Problem
I currently have a method in my models/listing.rb which has a method like this:
def self.lookup_info(val)
# Fetch some data from the internet
return{ price: value1, title: value2, isbn: val }
end
When users plug in val into views/listings/_form.html.erb when creating a new listing, I want to call lookup_info and have it fill in the rest of the form if a result (not nil) is returned.
Setup
controllers/listings_controller.rb
def new
#listing = Listing.new
end
views/listings/new.html.erb
<%= render 'form', listing: #listing %>
views/listings/_form.html.erb (I use div tags in actual code, but don't include below for simplicity)
<%= form_for(#listing, :html => {class: "form-horizontal" , role: "form"}) do |f| %>
<%= f.label :isbn, "ISBN" %>
<%= f.text_field :isbn , class: "form-control" , id: "isbn_field", placeholder: "ISBN (10 or 13 digits - no dashes)", autofocus: true %>
<%= f.label :price, "Price" %>
<%= f.text_field :price , class: "form-control" , id: "price_field", placeholder: "Price" %>
<%= f.label :title, "URL" %>
<%= f.text_field :title , class: "form-control" , id: "title_field", placeholder: "Title" %>
<%= f.submit class: "btn btn-primary btn-lg" %>
<% end %>
What javascript and rails do I need to make the _form.html.erb update when a user types in users_isbn, I call lookup_info(users_isbn) and then get an updated partial such that the values of the fields are set to the results.
Example of response:
<%= form_for(#listing, :html => {class: "form-horizontal" , role: "form"}) do |f| %>
<%= f.label :isbn, "ISBN" %>
<%= f.text_field :isbn , class: "form-control" , id: "isbn_field", placeholder: "ISBN (10 or 13 digits - no dashes)", value: lookup_info(users_isbn)[:isbn] autofocus: true %>
<%= f.label :price, "Price" %>
<%= f.text_field :price , class: "form-control" , id: "price_field", placeholder: "Price", value: lookup_info(users_isbn)[:price] %>
... <!-- Same idea for title -->
<% end %>
Current Start with Javascript
Here is what I have so far:
_form.js.erb (not sure if this would be the right name for the js file)
var isbnField = document.getElementById('#isbn_field').value;
if (isbnField.length == (10 || 13)){
var ajaxResponse = $.ajax({
url: "listings/lookup",
type: 'GET',
data: {isbn: $('#isbn_field').val()}
});
ajaxResponse.success(function(){
alert("Success"); # I would actually want to <%= j render #name of form partial with values %>
});
ajaxResponse.error(function(){
alert("Could not find that ISBN");
});
}
I'd suggest doing it as follows.
listings_controller.rb
# your new action
# your search action
def search
#foo = lookup_info(val)
# You might have to change this line to something like
# self.lookup_info(val) since I can't see the exact application of
# your lookup_info method. But the idea is you would want to put
# the return values into your #foo.
if #foo
respond_to { |format| format.js { render listings/success }
else
respond_to { |format| format.js {render listings/failure }
end
end
Explanation for controller action:
Your form would be submitting to the controller action search. If #foo is valid, meaning if the search is successful, it will render the successful partial view which we will be creating, else we will be rendering a view to handle failed form submissions (assuming you need it).
routes.rb
get "my-search-url", to: "listings#search", as: "my_search_url"
# you can set your own route names
# i assume your form is a get instead of post action
Now for your form, change it to form_with
<%= form_with(url: my_search_url_path) do |f| %>
If you are using Rails 4 instead of Rails 5, you can't use form_with, instead you'd have to use remote: true which would handle the ajax request for you.
Lastly, in your views, you need these 2 components, the js.erb and the partial
success.js.erb
$("#holder-for-search").html("<%= j render partial: 'listings/success' %>");
$("#bigger-holder-for-search").fadeIn("1000");
# note that the file name has to be the same as what your respond_to is rendering in your search action
# also remember to create a failure.js.erb too to handle the failed search
_success.html.erb
# render what you want to show if search is successful
And in your new.html.erb or wherever the form is displayed, simply have your relevant div with the correct ID tags (such as #holder-for-search)
<div id="bigger-holder-for-search" style="display:none;">
<div id="holder-for-search">
</div>
</div>
// and you can consider fading everything else out to fade in your search response
In summary, to reproduce an AJAX response, you need 4 components:
1) In your controller action, you need respond_to { |format| format.js }
2) You need to have a corresponding js.erb in your view (must be named exactly either like the controller action, or the respond_to response)
3) The partial to be rendered by your js.erb
4) A remote: true action. If its a link, you include it in the link, if its a form, you include it in your form. In rails 5, form_with implies remote: true hence you don't need to explicitly type that out.

How to do the calculation without any models in Rails?

I need to get an integer(#integer) from the form in my root_path, do multiplication (#integer*45) and display the result on the same page. How can I do it without any models in my application?
Please, share your best practice. Thank you!
I was trying to do next:
CalculatorsController
def calculation
#integer = params[:integer]
#result = #integer*45
end
def result
end
root.rb
root :to => 'calculators#result'
resources :calculators, :collection=>{:result => :get, :calculation => :post}
calculators/result.html.erb
<% form_tag root_path, :html => {:method => :post} do %>
<%= label_tag 'integer' %>
<%= text_field_tag :integer %>
<div><%= submit_tag 'OK' %></div>
<% end %>
I'll do it with ajax, so there is no need for page refresh:
First, update the routes, for your example you only need two routes, one get (or root) and one post.
routes.rb:
Rails.application.routes.draw do
root 'calculators#result'
post 'calculators/calculation'
end
Next, update your view:
Change the url in your form_tag where the data will be sent (to calculation action instead of result).
Add remote: true option to enable ajax.
Add a tag where you will display your result.
result.html.erb:
<% form_tag calculators_calculation_url, remote: true do %>
<%= label_tag 'integer' %>
<%= text_field_tag :integer %>
<div><%= submit_tag 'OK' %></div>
<% end %>
<div id="total"></div>
And create a view for calculation action, but since you are using ajax, you will create it as js.erb and include the required javascript (or jQuery) to update your view (i'm using jQuery in the example).
calculation.js.erb:
$('#total').html('<%= #result %>')
Now when you click submit, your form will be sent to calculation action and will update the div with #result.
Just add the field to your form...
<% form_tag root_path, :html => {:method => :post} do %>
<%= label_tag 'integer' %>
<%= text_field_tag(:integer, #integer) %>
<% if #result.present? %>
<br>
Result is: <%= #result %>
<br/>
<% end %>
<div><%= submit_tag 'OK' %></div>
<% end %>
And then render result in your calculate...
def calculation
#integer = params[:integer].to_i
#result = #integer*45
render :result
end
Your result view (result.html.erb) is getting its data from the result method, not calculation. Update your controller as follows:
def calculation
#integer = params[:integer]
end
def result
#result = #integer*45
end
You then need a tag to display your result in the view, something like:
<p> <%= #result %> </p>

Rails, trying to run a method from one controller to another gives Unknown Format

Ok,so basically I upload an image, and I just want to reload my partial when an image is uploaded.
Every Language has many images. (Weird structure of the app, yeah.)
I want to redirect from a method from the images_controller to a method of the languages_controller.
On my images_controller:
def create
#image = Image.new(image_params)
if !params[:image][:image].nil?
if #image.save(image_params)
#language = Language.find(params[:image][:language_id])
#language.increment(:last_position)
#language.save
redirect_to load_language_partial_path(#language),:remote => true
end
else
respond_to do |format|
format.js {render :action => 'required_fields'}
end
end
end
And the method on my languages_controller:
def load_partial
#language = Language.find(params[:id])
#image = Image.new
#images = #language.images.order(priority: :asc)
respond_to do |format|
format.js
end
end
The thing is when I run the load partial from a link in my view, it runs perfectly, but with this it gives me
ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/languages_controller.rb:10:in `load_partial'
I tried removing :remote = > true, but the same thing.
Is what I am trying to do not a good practice? Should I try some other way?
Thanks for reading.
EDIT
In my language partial I got a form in which I call the create function for #image
<%=form_for #image , url: images_create_path, remote: true, multipart: true, authenticity_token: true, html: {class: "form-horizontal", :style=> "" } do |f|%>
<h3 class="" style="float:left;margin-top:5px;"> Upload Image: </h3>
<div style="">
<span>
<%= f.file_field :image, :class => 'btn btn-default', 'data-show-upload' => false, :accept => 'image/*', :style=> 'margin-left:10px; float:left' %>
<%= f.number_field :language_id, :value=> #language.id, :style=> 'display:none' %>
<%= f.number_field :priority, :value=> #language.last_position, :style=> 'display:none' %>
</span>
<span>
<%= submit_tag "Upload",:class => 'btn btn-primary', :style=> "margin-left:10px;height:44px" , data: { disable_with: "Uploading..." } %>
</span>
</div>
<% end %>
And my load_partial.js.erb
$('.page-content').html('<%= j(render partial: "/languages/languagePartial") %>')
Instead of
redirect_to load_language_partial_path(#language),:remote => true
Try :
protocol = 'https://' or 'http://'
redirect_to protocol: protocol, controller: "languages", action: "load_partial", format: "js", languages: #language
You can skip protocol part if you want. I just gave it as I used it for my purpose. So you can use only:
redirect_to controller: "languages", action: "load_partial", format: "js", languages: #language
languages at the end is the parameter you want to pass, you can pass multiple parameters also separated by comma(,).

Rails unknown format on AJAX

I'm trying to implement a very simple file form using the remotipart gem. Most of my files are the exact same as the tutorial ones:
timeline.html.erb :
<%= form_tag new_feed_path(:format => "js"), remote: true, :html => { :multipart => true } do |f| %>
<%= hidden_field_tag :brief_id, #brief.id %>
<%= file_field_tag :file %>
<%= submit_tag "Send", class: "btn btn-success" %>
<% end %>
briefs_controller.rb
def new_feed
puts params
respond_to do |format|
format.js
end
end
new_feed.js.erb
alert('success!');
<% if remotipart_submitted? %>
alert('submitted via remotipart')
<% else %>
alert('submitted via native jquery-ujs')
<% end %>
But everytime I submit the form, I get the following error in the logs:
Processing by ResourcesController#create as HTML
Completed 406 Not Acceptable in 14ms
ActionController::UnknownFormat - ActionController::UnknownFormat:
Did I miss something ? I know ajax file upload can be tricky on RoR, but remotipart seems to be a viable solution.
EDIT I managed to fix the first issue by adding :format => "js" , but now I face another problem: none of the form datas are sent. In fact, here are the sent params:
{"controller"=>"briefs", "action"=>"new_feed"}
Check out the example from Remotipart's docs.
Looks like you're not passing :html => { :multipart => true } to form_for
try it
<%= form_tag new_feed_path, html: {multipart: true }, method: :post, remote:true do |f| %>
<%= hidden_field_tag :brief_id, #brief.id %>
<%= file_field_tag :file %>
<%= submit_tag "Send", class: "btn btn-success" %>
<% end %>
edit
try it
install this gem pry
RailsCast Pry
briefs_controller.rb
def new_feed
binding.pry #just to be sure that this action is not called
puts params
respond_to do |format|
format.js { render 'new_feed') # modify this
end
end

Resources