My Multiupload Form doesn't work as expected:
# app/views/activeadmin/dashboard/_import_cves.html.erb
<%= form_tag admin_dashboard_import_cves_path, method: :post, multipart: true do %>
<%= file_field_tag 'files', multiple: true %>
<%= submit_tag 'Import CVEs' %>
<% end %>
# app/admin/dhasboard.rb
ActiveAdmin.register_page "Dashboard" do
menu priority: 1, label: proc { I18n.t("active_admin.dashboard") }
page_action :import_cves, method: :post do
files.each do |f|
logger.debug f
end
redirect_to admin_dashboard_path
end
content title: proc { I18n.t("active_admin.dashboard") } do
columns do
column do
panel 'Upload CVEs' do
ul do
render 'activeadmin/dashboard/import_cves'
end
end
end
end
end
end
So... doing nothing special, yet. My form is displayed, I select multiple files (Chrome & Firefox on MacOS) and... Error:
undefined method `each' for #<ActionDispatch::Http::UploadedFile:0x0000000107415070 #tempfile=#Tempfile:/var/folders/6d/qr_wv8mx1zsgz0742b1j6p440000gn/T/RackMultipart20230203-9446-xlwanr, #original_filename="blc", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name="files"; filename="blc"\r\nContent-Type: application/octet-stream\r\n">
The thing is, I definitely selected 3 files. Which are at least in the filesystem in rails tempfolder:
-rw------- 1 havoc staff 0B 3 Feb 14:53 RackMultipart20230203-9446-bzjcc2
-rw------- 1 havoc staff 0B 3 Feb 14:53 RackMultipart20230203-9446-k0zm3
-rw------- 1 havoc staff 0B 3 Feb 14:53 RackMultipart20230203-9446-xlwanr
(PS: yes, these testfiles are empty - just touched three of them - but happens with pictures/other files exactly the same)
Any Idea what's wrong here?
Maybe an additional note: I'm using, as you may suggest already, ActiveAdmin for this upload. But from my point of view, there is something wrong with post or something? Or the Params variable?
# app/views/activeadmin/dashboard/_import_cves.html.erb
<%= form_tag admin_dashboard_import_cves_path, method: :post, multipart: true do %>
<%= file_field_tag 'files[]', multiple: true %>
<%= submit_tag 'Import CVEs' %>
<% end %>
... worked (added [] to the file_field_tag). I just can't say how disappointed I'm that this wasn't anywhere in the documentation. Found it here: Rails file_field_tag with multiple files delivers random string to controller
Related
I'm trying to post a integer method behind a file in a post method in ruby on rails.
For this, I use hidden_field_tag, but it send a json to controller and I don't know how can I use this json.
I try below code:
<%= form_tag import_tasks_path, multipart: true do %>
<%= file_field_tag :file %>
<%= hidden_field_tag :owner_id, :value => 1 %>
<%= submit_tag "Import" %>
<% end %>
In controller, I want use file and 1 in a function:
Task.import(params[:file], params[:owner_id])
but the value of params[:owner_id] is: {value=>1}.
how can I post just value? like:
Task.import(params[:file], 1)
I try any way, but don't find solution, like:
view:
<%= hidden_field_tag :owner_id, 1 %>
controller:
params[owner_id]
or:
params[:owner_id].dup
This should be enough :
<%= hidden_field_tag :owner_id, 1 %>
If you can't access it in your desired controller with params[:owner_id], it might have a parent. Try to do a params.inspect in your controller, it will reveal its location.
BONUS
The reason it is giving "{value=>1}" when you give :value => 1, is that it gets into the hidden_field_tag's value arg as a hash, and they should be calling to_s on it.
I am using Rails 4.1 and I created a User class. When the user is created the can import an avatar. However at best I have gotten an "image" to show up but it doesn't load the actual image from the database.
I then tried to use this post to fix it but now I am just getting "No Route Matches". Here is my exact error:
No route matches {:action=>"show_image", :controller=>"users_controller", :id=>"1"}
It claims it is coming from this line in my index.html.erb:
<%= image_tag url_for(:controller => "users_controller", :action => "show_image", :id => user.id) %>
Here is my controller:
def show_image
#user = User.find(params[:id])
send_data #user.avatar, :type => 'image/png', :disposition => 'inline'
end
And my users index.html.erb:
<html>
<head>
</head>
<body>
<h1>Users</h1>
<table>
<tr>
<th colspan="1"></th>
</tr>
<% #users.each do |user| %>
<tr>
<%= image_tag url_for(:controller => "users_controller", :action => "show_image", :id => user.id) %>
<td><%= user.username %></td>
</tr>
<% end %>
</table>
</body>
</html>
Any ideas or suggestions would be highly appreciated. Thanks ahead of time.
Edit: This is what my routes look like:
Rails.application.routes.draw do
get 'sessions/login'
get 'sessions/login_attempt'
get 'sessions/home'
get 'sessions/profile'
get 'sessions/setting'
get 'welcome/index'
get 'users/new'
post 'sessions/login_attempt'
post 'sessions/logout'
resources :users
root 'welcome#index'
end
Edit: I have also tried adding the following to the Routes file as suggested by #Question and #j0k in the thread I was following before:
resources :users do
get 'show_image', :on => :collection
end
and
get 'users/show_image' => 'users#show_image'
I also tried this
get 'users/show_image'
However I still got the same error.
Missing Image Icon that I get:
Two lines from my Users class where I add in avatar:
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
When looking up the images in the database this is what I found... I ran the following command:
sqlite> select avatar_file_name, avatar_content_type, avatar_file_size from users;
and got:
|image/png|660726
|image/gif|3614
|image/png|282
...so it is getting no file name.
When I looked up the file in the path I found that in this:
/public/system/users/avatars/000/000/001/original my image 'up.png' existed. It also existed in ../medium and ../thumb as well.
Edit: Update from #RichPeck advice.
So I was <%= image_tag #user.avatar.url %> ...instead this is what I was doing...
<% #users.each do |user| %>
<tr>
<%= image_tag user.avatar.url %>
</tr>
<% end %>
I am somewhat confused on how <%= image_tag #user.avatar.url %> would get a specific user's Avatar. Doesn't #user reference All Users? However, I tried #RichPeck suggestion anyway. I added both <%= image_tag #user.avatar.url %> and <%= debug #user.avatar %>. But both gave me the following error:
undefined method `avatar' for nil:NilClass
Edit: I just went through the Paperclip tutorial and compared it to what I have. I found a few differences but I don't think any of it would make a big difference. However, I will post it here so if anyone knows what is going wrong they can help.
Edit or New Views
Paperclip
<%= form_for #user, :url => users_path, :html => { :multipart => true } do |form| %>
<%= form.file_field :avatar %>
<% end %>
My code (The main thing I would be concerned about is the :url => but I think it should be fine)
<%= form_for(:user, :url => {:controller => 'users', :action => 'create'}, :html => { :multipart => true }) do |f| %>
<p> Username:</br> <%= f.text_field :username%> </p>
<p> Email:</br> <%= f.text_field :email%> </p>
<p> Password:</br> <%= f.password_field :password%></p>
<p> Password Confirmation:</br> <%= f.password_field :password_confirmation%> </p>
<%= f.file_field :avatar %>
<%= f.submit :Signup %>
<% end %>
Controller
Paperclip
def create
#user = User.create( user_params )
end
private
def user_params
params.require(:user).permit(:avatar)
end
My Code
def create
#user = User.new(user_params)
if #user.save
flash[:notice] = "You signed up successfully"
flash[:color]= "valid"
else
flash[:notice] = "Form is invalid"
flash[:color]= "invalid"
end
render "new"
end
private
def user_params
params.require(:user).permit(:username, :email, :password, :avatar)
end
Edit: After looking at it for a bit I realized I was trying to access the users page w/o my session. I was doing localhost:3000/users not localhost:3000/users?id=1. So my ID was never being passed.
I had to add the following to my Users Controller:
def index
#users = User.all
#user = User.find(params[:id]) # <--- Added this line
end
However, <%= image_tag #user.avatar.url %> still shows the default blank image. But I have been able to get <%= debug #user.avatar %> to work. This is the output for the debug command.
--- &70308396554900 !ruby/object:Paperclip::Attachment
name: :avatar
instance: !ruby/object:User
attributes:
id: 1
username: jones1
email: stupid1#stupid.com
encrypted_password: $2a$10$dvvLzRCQQVngFpt5TfPqJOtU8s02GUj6UOHlzibWi1CaQFY1BA8tS
salt: $2a$10$dvvLzRCQQVngFpt5TfPqJO
created_at: 2014-05-10 05:19:07.138281000 Z
updated_at: 2014-05-10 05:19:07.138281000 Z
avatar_file_name:
avatar_content_type: image/png
avatar_file_size: 397
avatar_updated_at: 2014-05-10 05:19:06.715067000 Z
options: &70308396554880
:convert_options: {}
:default_style: :original
:default_url: /images/:style/missing.png
:escape_url: true
:restricted_characters: !ruby/regexp /[&$+,\/:;=?#<>\[\]\{\}\|\\\^~%# ]/
:filename_cleaner:
:hash_data: ':class/:attachment/:id/:style/:updated_at'
:hash_digest: SHA1
:interpolator: &70308352640280 !ruby/module 'Paperclip::Interpolations'
:only_process: []
:path: ':rails_root/public:url'
:preserve_files: false
:processors:
- :thumbnail
:source_file_options: &70308351975980 {}
:storage: :filesystem
:styles:
:medium: 300x300>
:thumb: 100x100>
:url: /system/:class/:attachment/:id_partition/:style/:filename
:url_generator: !ruby/class 'Paperclip::UrlGenerator'
:use_default_time_zone: true
:use_timestamp: true
:whiny: true
:check_validity_before_processing: true
post_processing: true
queued_for_delete: []
queued_for_write: {}
errors: {}
dirty: false
interpolator: *70308352640280
url_generator: !ruby/object:Paperclip::UrlGenerator
attachment: *70308396554900
attachment_options: *70308396554880
source_file_options: *70308351975980
whiny: true
Edit: Last edit for the night before I have to go to sleep. I also did <%= debug #user.avatar.url %> and it returned the following: --- /images/original/missing.png?1399954308
Since you're using paperclip, and to help maintain clarity for anyone looking at this in future:
Paperclip
When you use Paperclip, it creates an object & appends to your
original ActiveRecord object. When you define has_attached_file :____, the name of that element is what the Paperclip object is
called, meaning you'll be able to call #user.____ to access it
The problem you have is you're using another process to load your image. This is totally unnecessary as, as pointed out in the comments, Paperclip automatically assigns the .url method to the appended Paperclip object
You should be able to call <%= image_tag #user.avatar.url %> to output the relvant image. I know you know this, but I want to help anyone who may look at this thread in future
Error
In terms of your error, having looked at your comments & updates, it seems like it's either a problem with how you're calling the image, or perhaps how it's stored in the db
Can you do this for us:
<%= debug #user.avatar #-> this will show the entire avatar object %>
I believe your db will not have the correct columns, hence Paperclip pulling the wrong filename or something. There will be a really trivial error somewhere
In general the setup appears to be fairly complicated - considering you want to display a user image. For simply things like user image I am using paperclip for my projects: https://github.com/thoughtbot/paperclip .. you may want to take a look at it. It automates image upload, resize, etc. I used it in several projects and never hit any issues.
If that's not what you need, perhaps you let me know what exactly you are trying to do.
I am using Carrierwave for file uploading and have got the following form, which allows me to submit several files:
<%= form_tag load_patterns_contacts_path, multipart: true, multiple: true do %>
<%= file_field_tag 'qqfile[]', id: "upload_pattern", multiple: true %>
<%= submit_tag "Load", id: "save_pattern", :class => 'btn btn-primary btn-success', multiple: true%>
<% end %>
Here is the code in my controller, which load submited files to the server:
#uploader = EmailPatternsUploader.new
params[:qqfile].each do |p|
tempfile = open(p.original_filename)
puts tempfile
#uploader.store!(tempfile)
end
redirect_to contacts_path
flash[:success] = "Uploaded successfully."
It works fine, if filename looks like "text.xlsx", "image.jpg" etc. But if it is contains special symbols like "_partial.html.erb" then I have got Errno:ENOENT (No such file or directory - _partial.html.erb)
I have tried to add
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\_\-\+]/
in my carrierwave.rb initializer, but it gives no result.
Thanks in advance for help!
UPDATE:
I have understood, that the problem not in special symbol "_", but in the fact, that samples I am trying to upload contains two dots ("."). I think I need to modify regular expression in order to avoid two dots
UPDATE:
I am sorry for the last comments. I have understood, that the matter not in special symbols at all and not in a name of file. The problem that i can upload files only from {Rails.root} path. If I choose another directory, I have got aforementioned error and cannot upload a file. How can I configure Carrierwave path directory?
Finally find an answer on my question.
The error was in these strings of code:
params[:qqfile].each do |p|
tempfile = open(p.original_filename)
puts tempfile
#uploader.store!(tempfile)
end
I have understood, that I need to pass an object ActionDispatch::Http::UploadedFile in Carrierwave store! method. Thats why the mentioned above code shall be the following:
params[:qqfile].each do |p|
puts p.original_filename
puts p
#uploader.store!(p)
end
==================================================================================
Hope someone find this solution for multiple file uploading with Carrierwave and without JQuery useful.
1) Create an uploader, using Carrierwave.
rails g uploader EmailPatterns
2) Create a custom action for your controller (watch Railscast#35 and Railscast#38 to make it clear) and put there something like this (load_patterns in my case):
def load_patterns
#uploader = EmailPatternsUploader.new
params[:qqfile].each {|p| #uploader.store!(p)}
redirect_to contacts_path
flash[:success] = "Uploaded successfully"
end
To make it work you need to specify custom route(config/routes.rb) for your action:
resources :contacts do
collection { post :load_patterns}
end
and to create a form, where you will get params with your uploading files (see p.3)
3) Create form, where you need to specify the option multiple:true in order to allow user to select several files to load (param name with [ ] is a necessary requirement, because we are loading several files) :
<%= form_tag load_patterns_contacts_path, multipart: true, multiple: true do %>
<%= file_field_tag 'qqfile[]', id: "upload_pattern", multiple: true %>
<%= submit_tag "Load", id: "save_pattern", :class => 'btn btn-primary btn-success', multiple: true%>
<% end %>
Then your custom action will work.
I am trying to insert a text after checkout email message. I'm found template in spree/order_mailer/confirm_email.text.erb
<%= Spree.t('order_mailer.confirm_email.dear_customer') %>
<%= Spree.t('order_mailer.confirm_email.instructions') %>
============================================================
<%= Spree.t('order_mailer.confirm_email.order_summary') %>
============================================================
<% #order.line_items.each do |item| %>
<%= item.variant.sku %> <%= raw(item.variant.product.name) %> <%= raw(item.variant.options_text) -%> (<%=item.quantity%>) # <%= item.single_money %> = <%= item.display_amount %>
<% end %>
============================================================
<%= Spree.t('order_mailer.confirm_email.subtotal', :subtotal => #order.display_item_total) %>
<% #order.adjustments.eligible.each do |adjustment| %>
<%= raw(adjustment.label) %> <%= adjustment.display_amount %>
<% end %>
<%= Spree.t('order_mailer.confirm_email.total', :total => #order.display_total) %>
<%= Spree.t('order_mailer.confirm_email.thanks') %>
So I don't know how to add some text after this, there are no any selectors:
Deface::Override.new(
:virtual_path => "spree/order_mailer/confirm_email",
:insert_bottom => '*',
:partial => "spree/shared/confirm_email",
:name => "confirm_email",
:original => '3a8c298b4d9884a4d9f842b23fcb4fabf92ef0f3'
)
Could you advice me any ways to solve this?
Found solution here: How to add Spree email attachment (image) from products.images?. I'm created a new template /app/views/spree/order_mailer/confirm_email.text.erb and added my code here.
Short answer: You can't.
Long Answer: Unfortunately you cannot deface a text file as I tried recently. Reason is Deface needs structured data to parse the view, as detailed in the Spree Group discussion.
Only .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface are the only override files allowed:
Deface::DSL does not know how to read '/spree/app/overrides/spree/order_mailer/confirm_email.text/append_text.text.erb.deface'.
Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface
Interestingly deface is actually able to test the selector on the file but still cannot override:
$ bundle exec rake deface:test_selector['spree/order_mailer/confirm_email.text',"erb:contains('order_mailer.confirm_email.thanks')"]
Querying 'spree/order_mailer/confirm_email.text' for 'erb:contains('order_mailer.confirm_email.thanks')'
---------------- Match 1 ----------------
<%= Spree.t('order_mailer.confirm_email.thanks') %>
The only thing you can do then is to override the file by creating app/views/spree/order_mailer/confirm_email.text.erb
I'm trying to add multiple product skus to an order at once.
Product has_many skus,
Order has_many order_lines
So in my order, I pull up a product and see all its skus (brown-small, brown-large) I then enter the qty of each I want to put on the order.
For some reason, it is only passing the :qty_sold params, and not the :sku_id - any reason why?
Routes:
post '/order_lines/create' => 'order_lines#create', :as => :create_order_lines
Form:
<%= form_tag create_order_lines_path do %>
<%= hidden_field_tag :order_id, #order.id %>
<% #product.first.skus.each_with_index do |sku, index| %>
<%= text_field_tag "order_lines[#{index}]", :sku_id, {:value => sku.id } %>
<%= sku.colour %>
<%= text_field_tag "order_lines[#{index}]", :qty_sold, {:value => ''} %>
<% end %>
<%= submit_tag "Add" %>
<% end %>
Output:
Started POST "/order_lines/create" for 127.0.0.1 at Fri Mar 16 23:13:27 -0400 2012
Processing by OrderLinesController#create as HTML
Parameters: {"commit"=>"Add", "order_id"=>"1", "authenticity_token"=>"JmImxbFUGLdM6Vt0rrS9RabSCUi1kV2QRTpWp34BBb4=", "utf8"=>"\342\234\223", "order_lines"=>{"0"=>"7", "1"=>"8", "2"=>"", "3"=>"9", "4"=>"", "5"=>""}}
This line is setting the key that you're having problems with
text_field_tag "order_lines[#{index}]"
So basically you're saying order_lines[X] = and since :qty_sold is the last option set to that key it's getting assigned that value.
To accomplish what you're trying to accomplish you would need to go a level deeper, like this
<%= text_field_tag "order_lines[#{index}][qty_sold]", :qty_sold, {:value => ''} %>
Honestly though, you should consider looking into the fields_for helper it does everything you want to accomplish and is more abstract.
This is untested but I think it should work
<% #product.skus.each do |sku| %>
<%= fields_for :order_lines do |order_line_fields| %>
<%= order_line_fields.text_field :sku_id, {:value => sku.id} %>
<%= sku.colour %>
<%= order_line_fields.text_field :qty_sold %>
<% end %>
<% end %>