using uploaded text file's contents as parameter for new object - ruby-on-rails

I'm uploading a plain text file and I'd like to use the text within as the parameters for a new object. Here's my attempt so far, in views/scans/new.html.erb:
<h1>New scan</h1>
<%= form_for :file_upload, :html => {:multipart => true} do |f| %>
<p><%= f.file_field :raw %></p>
<p><%= f.submit "Upload" %></p>
<% end %>
raw is a text attribute of the scan model. This yields the error:
Routing Error
No route matches [POST] "/scans/new"
Try running rake routes for more information on available routes.
I can tell from Google that I need to File.read() but I don't know where I would do it.

in model
def raw= (file)
File.open(file,"r") do |f|
self.your_atrribute = f.readlines.join("")
end
end

Related

Can't find submitted file in params

All I'm trying to do is parse a file with Rails, but I can't for the life of me pass it through to my controller. I can't even get the file name or path to show up in the submitted params.
My form:
<%= form_tag({url: upload_path}, method: :patch, multipart: true) do %>
<%= file_field(:user, :csv, :multiple => false, class:"file-field") %>
<%= submit_tag 'Submit', class:"btn" %>
<% end %>
My controller:
def upload
file = params[:user][:csv] #params[:user] is nil
#parse file
end
According to the rails docs, I thought the file should be contained in params[:user][:csv], but I must be misinterpreting something because params[:user][:csv] is nil, and neither "user" or "csv" show up anywhere in the params.
I want to be able to get the file path, and then using that, parse the file. What am I doing wrong?
Use this for file_field_tag
<%= file_field_tag('user["csv"]', :multiple => false, class:"file-field") %>
Options should go after name and I don't understand what is :csv in that case if :user is name

How to fix undefined method error in rails?

I keep getting an error saying: undefined method `androids_path' for #<#:0x007ff5edcd5330>. It's saying the error is at line 1 in new.html.
The name of the model is Android and is at android.rb. Any advice on how to fix this?
In androidapps_controller.rb:
def new
#android = Android.new
end
In new.html I have:
<%= form_for(#android, validate:true) do |f| %>
<% #android.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<%= f.submit %>
<% end %>
routes.rb
Grabapp::Application.routes.draw do
root :to => 'iosapps#index'
get "static_pages/home"
get "static_pages/add"
get "static_pages/about"
devise_for :users
resources :iosapps
resources :androidapps
Add to your routes.rb:
resources :android
You're error is because you've asked form_for to do resource based routing!
<%= form_for(#android, validate:true) do |f| %>
But you didn't define the resource based routing required to make it work!
Your model and controller are not matched (Android vs AndroidApp), so need to specify the correct url in your form:
<%= form_for(#android, validate: true, url: androidapps_path) do |f| %>
<%= form_for(#android, validate:true) do |f| %> automatically sets up the correct HTTP method (normally POST or PUT) with the HTML markup for a form. It also assumes you have a url set up called /androids in the case of POST and /androids/:id in the case of PUT. So for this to work you need to tell rails to create the necessary routings. This is done by adding the following line in config/routes.rb namely resources :androids.
This is why is is better to match up your model and controller names, Rails can then automatically infer the correct controller actions based on the model name.
You need to read up a bit more on routing and how it works. Do it here: http://guides.rubyonrails.org/routing.html

Create an upload controller action for Rails app

I'm making a Rails app, and want to add an upload feature with allows users to upload multiple entries at once through an Excel spreadsheet as opposed to entering one entry at a time.
Ideally, I was hoping to add a separate Upload/Submit portion to the bottom of the new.html.erb file (the bold portion being the Upload HTML.erb):
...
<div class="actions">
<%= f.submit %>
</div>
<% end %>
**<div class="field">
Or Upload Multiple Entries <br />
<%= form_tag({:action => :upload}, :multipart => true) do %>
<%= file_field_tag 'multi_doc' %>
<% end %>
</div>**
Here is my routes.rb file:
Dataway::Application.routes.draw do
devise_for :users
resources :revenue_models do
get 'upload', :on => :collection
end
root :to => "home#index"
end
And my revenue_models_controller (haven't developed the action at all yet, now just a redirect):
...
def upload
redirect_to revenue_models_path
end
I have followed the rails guides for Uploading files as well as for Routing files and I keep getting an error when I attempt to open the /new view I have modified:
Routing Error
No route matches {:action=>"upload", :controller=>"revenue_models"}
Try running rake routes
When I run rake route, I get an entry for the upload action:
upload_revenue_models GET /revenue_models/upload(.:format) revenue_models#upload
In the end, what I would like to do is upload an excel file with multiple entries, parse it, and conditionally add each data row to my database, which I was under the impression I could specify in the upload action. Please help!
Please use form_for instead form_tag.
Second What is multi_doc is a field/attribute of revenue_model?. I guess is a field/attribute of revenue_model.
Third, Where is your instance variable revenue_model in the form?
Fourth, You have to create first a instance variable of your Model, on your action/controller where you are showing the form, for example #revenue_model = RevenueModel.new.
After try this code:
<%= form_for(#revenue_model, :method => :get, :html => {:multipart => true}, :url => { :controller => "revenue_models", :action => "upload"})) do |f| %>
<%= f.file_field :multi_doc %>
<%= f.submit :id => "any_id" %>
<% end %>
The question is very confusing, trying to clarify your question specifying the name of your actions and the names of the files in your views.
Regards!

Rails 3 routing not generating proper paths for new vs edit views

I'm getting some funkiness that is absolutely confounding me with Rails 3. I can't seem to get the routing to generate the proper path using the (mostly) standard _form style of the scaffold.
First off, I'm doing everything within an "admin" namespace. I'm finding that the form partial throws a routing error if I use admin_team_path(#team) to generate the path when creating a new Team, but then submitting the form when editing, it throws an error unless I use admin_teams_path.
admin_team_path(#team) where #team = Team.new throws this error:
No route matches {:controller=>"admin/teams", :action=>"show", :id=>#}
Meanwhile...
admin_teams_path(#team) where #team = throws this error:
The action 'edit' could not be found for TeamsController
In the latter case, it seems to be directing to the URL: http://localhost:3000/teams/1/edit - it's not recognizing the namespace properly.
Here's my full _form.html:
<%= semantic_form_for(#team, :url => admin_teams_path(#team)) do |f| %>
<%= f.semantic_errors %>
<%= f.inputs do %>
<%= f.input :user_id %>
<%= f.input :league_id %>
<%= f.input :name %>
<% end %>
<%= f.buttons do %>
<%= f.commit_button :button_html =>{:class => "primary"} %>
<% end %>
<% end %>
What gives? What's the right way to create this form partial so it works for both new and edit actions?
Namespaces seem to be such a mess to work with.
Presuming you have defined your routes in a RESOURCEful manner, like so:
namespace :admin do
resources :teams
end
Then, in your _form partial you can let rails take care of the action like so:
<%= semantic_form_for(["admin", #team]) do |f| %>
.... #rest of the code
<% end %>

Rails: Using form (collection select) to call show-action

A model named 'book' with attributes 'name' and 'id' is given. How can i use this collection select to call the show-action of a certain book? The one code mentioned below returns the following error message:
Couldn't find Book with ID=book_id
<% form_tag(book_path(:book_id)), :method => :get do %>
<p>
<%= label(:book, :id, 'Show Book:') %>
<%= #books = Books.find(:all, :order => :name)
collection_select(:book, :id, #books, :id, :name)
%>
</p>
<p>
<%= submit_tag 'Go' %>
</p>
<% end %>
book_path is generated once only, for the form tag itself. It won't be updated whenever your selection changes.
When you submit that form, it's going to request the following URL:
/books/book_id?book[id]=5
Since your book_path thinks book_id is the ID number you wanted, it tries to look that up. You could do what you want you by changing the code in your controller from:
#book = Book.find(params[:id])
to:
#book = Book.find(params[:book][:id])
But it kind of smells bad so be warned.
You can create a new route that is not based on the id, like
get 'books/show' # put this above your "resources :books"
and change your form to
<% form_tag books_show_path, :method => :get %>

Resources