two fields for one file - ruby-on-rails

In my form I have field for file uploading which is done with default rails methods, looking like this(I'm using simple_form here, to be clear):
= f.input :spec_url, as: :file
It generates nice and easily field with which user can select any file from his hard drive. But i would like to give users opportunity to simply type this information. since this is field for URL, it should be string field, possible to just fill in, WITH POSSIBILITY to upload something.
How can I achieve this? Some gems maybe?

You will need to have two fields (a string and a file):
= f.input :spec_url, as: :string, id: 'url-field'
= f.input :spec_file, as: :file, id: 'file-field'
Add some javascript (I'm using CoffeeScript) which will set the file name on the spec_url field:
$ ->
$('#file-field').on 'change', (e) =>
$('#url-field').val($(e.target).val())
And then you can do some conditional statements in your Ruby code:
if params[:object][:spec_file]
# Upload file
object.spec_url = params[:object][:spec_file].original_filename
else
# Open URL
object.spec_url = params[:object][:spec_url]
end
Add attr_accessor :spec_file to your model:
attr_accessor :spec_file
This is just a rough idea since I'm not sure what the context is. You might need to modify and style some of the code.
Update
You might also find this question helpful: Rails: upload a file OR store a url

Related

How to add a picture to a model (User) in Rails using ActiveStorage and the Cloudinary Upload Widget?

world!
After implementing Cloudinary's Active Storage Integration, it's easy to make it work in a form.
We just need to add to our simple_form_for a
<%= f.input :photo, as: :file %>
BUT, if we want to use the Cloudinary Upload Widget, there's no straightforward way of adding this file to the form.
What I have tried is:
1- let the widget upload the picture;
2- update the value of a hidden input with the url of the uploaded picture;
3- in the controller, when creating the model, download the picture and attach it to the model:
require 'open-uri'
file = URI.open(photo_url)
#user.photo.attach(io: file, filename: 'profile_photo.jpg')
# [...]
private
def photo_url
params.require(:user).permit(:photo_url)[:photo_url]
end
It works, BUT it uploads twice the same picture and - IMHO - is extremely inefficient.
Any ideas?
Thank you!
Good Luck, Have Fun!

Attachinary : can I keep the original filename?

I use Attachinray with Cloudinary, for direct upload. Everything works very well, except the fact that when I try to save files in my controller, I do not have the original filenames.
Here is a sample of my code:
class User
has_attachments :pictures
end
My form :
= simple_form_for #user do |f|
= f.attachinary_file_field :pictures, as: :attachinary
= f.submit t('.submit')
Once my files are uploaded, when I submit the form, I lost original filenames. Here is what I get for one file :
{"public_id"=>"ryfeummp2ikmzkss4cfy", "version"=>1427873505, "signature"=>"8475fccf9914dd05f6fg622ee39c1cb7ddd25f11", "width"=>78, "height"=>100, "format"=>"png", "resource_type"=>"image", "created_at"=>"2015-03-24T14:48:25Z", "tags"=>["development_env", "attachinary_tmp"], "bytes"=>19882, "type"=>"upload", "etag"=>"1fefdabba402263d18a92238ba4275c9", "url"=>"http://res.cloudinary.com/dd9blzv7x/image/upload/v1427873505/ryfeummp2ikmzkss4cfy.png", "secure_url"=>"https://res.cloudinary.com/dd9blzv7x/image/upload/v1427873505/ryfeummp2ikmzkss4cfy.png"}
Does anyone know if it's possible to keep track of the original filename ?
If you wish to have the original image's filename, you can use something like the following in your controller code:
params[:user][:pictures].each do |picture|
# Do whatever you need with picture.original_filename
end
If you need to store them in your DB, you'll probably need to permit it first and not access them directly.
Alternatively, you can tell Cloudinary to set the uploaded image's filename as the original filename:
f.attachinary_file_field :pictures, as: :attachinary, cloudinary: {use_filename: true}
Note that random characters are added in default. For more information:
http://support.cloudinary.com/hc/en-us/articles/202520762-How-to-upload-images-while-keeping-their-original-filenames-

Wrap images from text field into image_tag

I would like to create a helper or change the model.rb to behave like:
Post model has a text field, which contains urls, all separated with new lines.
On create or update, rails scans this field, when it finds url like:
http://i.imgur.com/imanimage.png
http://i.imgur.com/anotherimage.png
Then it leaves them as is, but in the show action it renders them as:
= image_tag('http://i.imgur.com/imanimage.png', class: 'my-image-class')
= image_tag('http://i.imgur.com/anotherimage.png', class: 'my-image-class')
Probably a helper method could do this.
Does the text field store anything else but the urls? If it does, you should consider creating helper using regex to get all urls and change these to <img src=''/>,
If not, you can use in haml/erb file.
Model.text.each_line do |m|
image_tag(m, class: 'my_img')
end
Reference: http://ruby-doc.org/core-2.1.0/String.html#method-i-lines
If you're saving these URLs in your database, you it should be quite a simple procedure:
#app/models/image_url.rb
Class ImageURL < ActiveRecord::Base
end
#app/controllers/image_urls_controller.rb
def show
#url = ImageURL.find(params[:id])
end
#app/views/image_urls/show.html.erb
<%= image_tag(#url, class: 'my-image-class')
If you add some more context to your question, I'll be able to give you a more refined answer!

Ruby on Rails, pass Image from one object to another or from NEW to CREATE

I'm pretty new to Ruby on Rails.
I changed this thread, because i recognized that I was searching for my problems' solution at the wrong end.
Here's my Problem:
I got a Class ProfileProposal which I upload an Image with(Using CarrierWave).
Now I want to convert ProfileProposal to another class, called Profile.
So I pass all the Information to the NEW-Form of Profile.
Works fine with strings, but not with Images.
What I've already tried/done:
Pass the Image as GET Param to the Create Method:
<%= form_for #profile, :url => { :action => "create", :controller => "profiles", :image => #profile_proposal.image } do |f| %>
#
Which now works, so I DO have the image-url.
What's not working is the following:
#profile = Profile.new(params[:profile], :image => new_image_url)
# OR
#profile.image = new_image_url
#profile.image still has the default value given by Carrierwave.
Thanks in advance!
I'm coming from using paperclip, not carrierwave, so I'll try to keep this high level. But I have an idea for you. Maybe you can set the filename of the new attachment before it exists, then move the image to that path. With paperclip this would play out like:
#profile.image_file_name = "profile.jpg"
# creates the directory of the new path. There's probably a better way to do this:
FileUtils.mkdir_p #profile.image_file_path.gsub(/[^\/]*$/,'')
FileUtils.mv #profile_proposal.image_path #profile.image_path
You should embed a hidden field in that Profile form, referencing ProfileProposal by some ID. Then while handling the form server side, after everything is validated and ready for save, you should copy the image using some read/write methods, from ProfileProposal instance to Profile instance. I'm not sure how CarrierWave wants you to do this.
I finally fixed that problem, by using paperclip and creating a new Instance via
Profile.create(:name => #profile_proposal.name, :image => #profile_proposal.image)

Rails form tag errors out when encountering a binary field

I have a binary column type in my "users" table and when I try to include that field within simple_form_for tag, I get an error.
= simple_form_for #user
= f.input :secret_number
Here's the error-
No input found for binary
Some extra information that might be useful - so I am storing some encrypted information in this column. The data is encrypted at the time ActiveRecord is saved. But in the form that is presented to the user I want to show padded up data, something like - *****456". I have written the following method to decrypt/pad-up secret_number.
def secret_number
decrypt_and_pad_up(self.secret_number)
end
You can see where the error is being raised in SimpleForm::FormBuilder#find_mapping. The reason you're getting this error is because simple_form asks Rails what type of data the given attribute contains--:binary in this case (Rails doesn't know or care that you overrode the secret_number method)--in order to decide what type of form field to generate. Since there's no way to know what kind of form field a binary attribute should use you get this error.
Naturally, the solution is in the docs. If you want it to display as a text input, use the :as option:
f.input :secret_number, :as => :string

Resources