I have two rails applications which are connected through an API. In the first rails app I have many users with avatar images. Now I want to send them through a file_field (in form_for) to the second rails app.
The problem is that I don't want manualy select the image-path for each user. Better would be if the image_path would be automaticaly inserted when the page is loaded. At the moment there is for each user a page where I select his avatar image and click on send.
The location of the images is on the first rails server. So this means that I want to send avatar images from one rails server to another with a file_field.
Is that somehow possible?
If you are trying to set a default image when opening a record for editing you have to do the following
In your edit view:
<%= form_for(#photo, :html => { :multipart => true }) do |f| %>
<%= f.text_field :name %>
<%= f.file_field :image %>
<%= f.submit "Change" %>
<% end %>
In your controller:
#photo = Photo.find(params[:id])
When you form gets displayed it will automatically assign the image in the database to the file_field.
Although the form might show "No File Selected", When you update your form your original image will still be there.
Related
Situation:
An order is created by ordercontroller create method into a orders table.
Then a video is uploaded by videoordercontroller create method into the videoorder table associated with the order_id.
I have this in the orders show page to upload the video to the order:
<%= form_for([#order, #video_order]) do |form| %>
<%= form.file_field :video %>
<%= form.submit "Upload", class: "btn btn-success" %>
This form technically disapears after submission but i am testing updating the video because i also want to give the ability to update the video in case a wrong video is uploaded.
I tried:
<%= form_for([#order, #video_order], :url => edit_order_video_order_path(#order.id, #video_order), remote: true ) do |form| %>
<%= form.file_field :video %>
<%= form.submit "Upload", class: "btn btn-success" %>
But this gives me the
"(No route matches [POST] "/orders/150/video_orders/150/edit")"
Which, of course this wouldn't work but i also can't figure out how to allow to update the video tables order_id from the same URL page. I don't want to send the user to a new page for convenience.
So basically, how can i allow updating the orders video in the video table?
Here's the models:
video_order model
belongs_to :order
validates :order_id, uniqueness: true
order order model
has_one :video_order
The video_order model has the order_id and video only.
the order model doesn't have a video_id column.
Also, if you see any associations being wrong or have better ways, feel free to let me know.
Rake:
edit_order_video_order GET /orders/:order_id/video_orders/:id/edit(.:format) video_orders#edit
PATCH /orders/:order_id/video_orders/:id(.:format) video_orders#update
PUT /orders/:order_id/video_orders/:id(.:format) video_orders#update
This is taking place in the Order show page
I have this method in the order controller:
def show
#user = current_user
#video_order = VideoOrder.new
end
This where the uploading of the video takes place. i also want to allow updating from it with a seprate form
form_for method has a options parameter, you can set the form method as 'patch' as follows:
form_for #object, url: 'some_url', method: 'patch'
Looks like this works for updating the table and not creating a new row:
<%= form_for(#order.video_order) do |form| %>
Only issue I'm currently having is the redirect after. I get "Cannot redirect to nil!" but i will figure that out soon enough.
Redirect needed to be along the lines of this:
redirect_to order_path(#video_order.order_id)
In orde to redirect back to the order show page
This solution ended up being so simple! :)
I have a form made with simple_form that accept csv file to be converted it in an xlsx file (operating some operation to manipulate data).
<%= simple_form_for order, url: convert_orders_url, html: {multipart: true} do |f| %>
<%= f.file_field :file %>
<%= f.submit "Convert" %>
<% end %>
In my controller:
def convert
filename = #call to function that return the file path
send_file filename
end
The problem I have is that I need to upload multiple file one by one.
Anyway every time I need to reload the page manually cause I cannot submit the form multiple times and I can't reload the page in the controller because it raise a Double Render Error, because of the "send_file".
Is there a way to submit a form multiple time without reload the page in Ruby on Rails?
You can use remote: true on your form to submit the form using AJAX without reloading the page. However, with file uploads you'll find that remote: true won't work out of the box and you'll need something like remotipart.
I'm trying to send a message with an attachment in Mailboxer Gem.
My stack is : Rails 4 and Ruby 2.1.1
However, I can see that attachment using CarrierWave is already supported as the link in the code below.
https://github.com/ging/mailboxer/blob/4b2681c1790b823f7b493fb00b41e9899bb90ebe/app/models/message.rb#L13
However, I did my setup exactly like that. Normal message without an attachment is going fine.
This is my code :
Controller :
def create_message
if params[:user].present? & params[:message].present? & params[:subject].present?
current_user.send_message(User.find(params[:user]), params[:message], params[:subject])
redirect_to inbox_path
end
end
This is my view code :
<%= form_tag do %>
<%= select_tag 'user', options_from_collection_for_select(User.all, :id, :fullname) %><br/>
<%= text_field_tag 'subject' %><br/>
<%= text_area_tag 'message' %><br/>
<%= submit_tag 'Send' %>
<% end %>
The above code is working fine and the messages are getting sent, however, when I try to add the file field to it like so and try changing the controller code, the attachment is not getting uploaded :
def create_message
if params[:user].present? & params[:message].present? & params[:subject].present?
current_user.send_message(User.find(params[:user]), params[:message], params[:subject], true , params[:attachment])
redirect_to inbox_path
end
end
View :
<%= form_tag do %>
<%= select_tag 'user', options_from_collection_for_select(User.all, :id, :fullname) %><br/>
<%= text_field_tag 'subject' %><br/>
<%= text_area_tag 'message' %><br/>
<%= file_field_tag 'attachment' %>
<%= submit_tag 'Send' %>
<% end %>
I think this is a problem with the strong params. In Rails 3 I could have used attr_accessible. However how do I ensure that the attachment field is not being blocked and allowed?
P.S - I have the carrierwave gem installed and I have even restarted my server multiple times.
Thanks.
I am changing my previous answer, because in fact it wasn't correct.
Basically, if your problem is like mine, it could easily be solved by adding :multipart => true to your form. At least in my case, that's why carrierwave was not picking up the attachments.
I tried to solve the problem by extending the mailboxer Message class and setting up and mounting a completely new carrierwave object with a different attribute name. Basically, this allowed me to avoid working with the attachment attribute defined in mailboxer and to customize the attachments.
But this got very messy with the extension of the mailboxer message.rb Class. So I finally abandoned that course. Still, having your own uploader instead of relying on the mailboxer attachment is very convenient, especially if you want or need to upload your files to a different directory or to the cloud.
So finally, I have created a new model for my attachments and mounted a new carrierwave uploader on it. In that way, I can customize it as I want without having to tweak mailboxer, which has very little in terms of documentation or support.
Probably this is not useful to you anymore, but might help others!
In my form, a user can upload images as part of the form but if that form fails validation, all of those images are lost.
Is there a way to repopulate those fields with the images they've submitted?
Yes, there's a way. For example, you can use CarrierWave. It has built in functionality to solve this issue. Code snippet right from README:
<%= form_for #user, :html => {:multipart => true} do |f| %>
<p>
<label>My Avatar</label>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</p>
As you can see there's a hidden field. Basically, CarrierWave saves a copy avatar between requests inside of avatar_cache field. On the form re-rendering it pulls image from the cache (if there's any). If you don't want to use CarrierWave, you could learn how to implement similar solution from it's sources.
I have 3 models. Users have multiple Portfolios and Portfolios have multiple Assets.
When a user signs in, that makes him a current_user by find_by_id. When they first register, it creates a portfolio for them. That becomes the current_portfolio.
Subsequent to this, they can create portfolios which redirects them to the list of all their portfolios. Clicking the link to each will make that portfolio the current_portfolio.
#current_portfolio = current_user.portfolios.find_by_id(params[:id])
The show view for portfolios has an assets form so that they can quickly add assets to the portfolio. This is where I get stuck. Because the assets form is on the portfolios show view, my Asset controller needs to reference current_portfolio, but this is in my Portfolio controller.
Portfolio Controller:
def show
#current_portfolio = current_user.portfolios.find_by_id(params[:id])
#asset = #current_portfolio.assets.build
end
When the form is submitted, it goes to my Assets controller Create function. Create can't simply have #current_portfolio because it's on a different controller. I also can't use find_by_id(params[:id]) because :id is not providing anything.
How do I reference the second model when I have 3 models? (Sorry I'm a newb to rails...)
EDIT Update: I thought I found the solution but realized it didn't work.
I passed <%= hidden_field_tag :portfolio_id, params[:id]%> in my form and set my Create in the Asset controller to be
def create
#asset = Asset.new(params[:asset])
#asset.save
end
but it's not getting the portfolio_id which is a required field in my model.
Full form in my view
<%= form_for(#asset) do |f| %>
<%= hidden_field_tag :portfolio_id, params[:id]%>
<%= f.text_field :asset_symbol %>
<%= f.text_field :shares %>
<%= f.text_field :cost %>
<%= f.text_field :purchase_date, :type=>'date' %>
<%= f.submit "+ Add to Portfolio" %>
<%end%>
My guess would be that the portfolio_id in the hidden field isn't coming back as part of the asset hash. Maybe it's as simple as assigning the #asset.portfolio_id = params[:portfolio_id] before the save. Check you logs to see EXACTLY what is coming back in the POST