How to browser multiple file with paperclip in rails4 - ruby-on-rails

I have three field
a) email
b) phone number
c) browse files (Here one link `add more file`)
When user click on add more file link then one more browse button appear and so on
I want to save all files when user click on submit button
How Can I do that with paperclip in rails 4
Model
User.rb
has_many invoices
accepts_nested_attributes_for :invoices, :allow_destroy => true
Invoice.rb
belongs_to :user
I have use field_for for invoice in view
controller
def new
#user = User.new
#user.invoices.build
end
def create
User.create(user_params)
end

It looks like your current setup will work well for one file, however if you want to add multiple files, you'll need to build the objects again & load a new fields_for to support that. To do this, I would recommend using Ajax:
I don't know if this will work, but this is how I would tackle the problem:
Put your fields_for into a partial
On your form, include "+" button with :remote => :true
Controller will handle AJAX request & build a new object
On successful AJAX request, load a partial with new fields_for
See if the submit includes all the files
Create fields_for Partial
Your form will likely look like this:
<%= f.fields_for :invoices do |field| %>
<%= field.file_field :image %>
<% end %>
You need to turn this into a partial:
<%= f.fields_for :invoices do |field| %>
<%= render :partial => 'images_fields', locals: {f: field} %>
<% end %>
Your partial could then look like:
<%= f.file_field :image %>
Include "+" Button On Your Form
On your form, you can just create a link like this:
<%= link_to "+", your_controller_action, :remote => :true %>
Controller Will Handle Ajax Request
#app/controllers/your_controller.rb
def new
#user = User.new
#user.invoices.build
respond_to do |format|
format.js { #user.invoices.build }
format.html
end
end
This should render a new object, which you can then append to the form with the returned JS:
#app/views/controller/new.js.erb
$("form").append("<%=j render :partial => 'images_fields', locals: {f: #user} %>")
See If It Submits All The Files
My code probably won't work as it needs debugging. However, this is the process I would use. If you try it, we can debug in the comments
Let me know how it goes!!

Related

Filling additional form parameters from one input

I'm fairly new to Rails and can't find any information on exactly how to do this.
Currently, users create items by filling in a form with URL, Title, Content, etc.
#resource = Resource.new(resource_params)
.
.
.
def resource_params
params.require(:resource).permit(:title, :url, :content, :name, :tags_as_string)
end
I want users to be able to input only the URL, and generate the input for the rest of the parameters using the MetaInspector gem (https://github.com/jaimeiniesta/metainspector), but then be able to go back to the created item and edit its content manually.
Can somebody point me in the right direction? I have a feeling I need to create some kind of helper method, but this is the real first programming I've encountered in my project.
To prevent users from passing value of any field except url, you will need to remove all fields but url from your new resource form.
app/views/resources/new.html.erb
<%= form_for(#resource) do |f| %>
<%= f.text_field :url %>
<% end %>
And in your controller action create, permit only :url in params.
app/controllers/resources_controller.rb
def create
#resource = Resource.new(params.require(:resource).permit(:url))
# Set other attributes using `metainspector`. See documentation for usage.
if #resource.save
redirect_to resources_path
else
render :new
end
end
You can have a separate form (with all the fields) for editing a resource manually and a different set of permitted params for update action.
app/views/resources/edit.html.erb
<%= form_for(#resource) do |f| %>
<%= f.text_field :url %>
<%= f.text_field :title %>
<%= f.text_field :content %>
<!-- Add other editable fields here -->
<% end %>
app/controllers/resources_controller.rb
before_action :fetch_resource, only: [:edit, :update]
def update
if #resource.update_attributes(resource_params)
redirect_to resources_path
else
render :edit
end
end
private
def fetch_resource
# Fetch `Resource` instance from database. Homework for you.
end
def resource_params
params.require(:resource).permit(:title, :url, :content, :name, :tags_as_string)
end
Note: This code is not tested. It is just to give you hints on how you should proceed. You might have to change some method/field names to make them suit your application.

Trying to fire an action in my controller when a selection in a drop down menu is made but getting a no route matches error

I'm building a web interface to accompany a mobile app I'm building. I have a drop down select menu that lists a bunch locations.
On selection of a location I want to make a call to a method in my controller and grab some destinations within the location that was selected (each location has several destinations).
I then would like to render my show template with these results allowing the user to select a destination and make a booking.
This is what I have so far:
My view with a list of resorts:
<%= form_tag :url => { :action => :show } do %>
<%= select_tag :resort , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
<% end %>
Controller:
class HomeController < ApplicationController
def index
#resorts = ["A","B", "C", "D", "E"]
end
def new
end
def edit
end
def create
end
def show
#activities = Parse::Query.new("Activity").tap do |a|
a.eq("resort", params[:resort])
end.get
end
end
Just slightly confused. Using form_for makes more sense to me with CRUD in mind and also because the form is object based.
I'd like to just take the selected resorted and pass it into a method in my controller that goes into a database and grabs a bunch of destinations. I then want to list these destinations on my show page where a user can click and be taken to another page where they can make a booking at that destination.
My above code doesn't work. I have resources :home in my routes file.
However when I try to load my page with the form I get:
No route matches {:action=>"show", :controller=>"home"} missing required keys: [:id]
How do I pull this off?
I went on my lynda account and pulled up a rails essential tutorial which I'll have to use to refresh my memory some time tomorrow but the tutor doesn't cover use of select_tag.
Would appreciate some help here
Thanks for your time
So a few thoughts. Not sure why you are using form_tag and also not sure why you aren't using Rails idiomatic conventions.
Declare a resource in your routes for #resorts, like so:
resources :resorts
Then just use Rails form_for helper like:
<%= form_for #resorts, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= f.select :resort, (insert your other options) %>
<%= f.submit "Create" %>
<% end %>
I have not tested the above code, so play around with it, but that should work.
However, let me save you some headache. Checkout SimpleForm.
For your models, you would want to setup an association between your locations and destinations.
class Location < ActiveRecord::Base
belongs_to :resort # or whatever the relation is
has_many :destinations
end
class Destination < ActiveRecord::Base
belongs_to :location # This assumes there is just a one-to-many relationship between Location and Destination
end
Make sure you have a LocationsController with all the actions.
In this case, your SimpleForm form would look something like this:
<%= simple_form_for #locations do |f| %>
<%= f.input :name %>
<%= f.association :password %>
<%= f.button :submit %>
<% end %>
That approach will make your life much easier. Take a look at the collections methods in Simple Form. Rails can make your life difficult with the built in form helpers.
Hope that helps!
In your routes, add
get '/choose_resort' => 'home#show' #you can name the get whatever
Then in your form...
<%= form_tag choose_resort_path do %>
That being said... you should have your query at a separate endpoint, and redirect to the show page. That should get you moving, methinks.
The show action needs an id of the object you are showing. Change your controller:
class HomeController < ApplicationController
def index
#resorts = [["A",1], ["B",2], ["C",3], ["D",4], ["E",5] ]
end
And your view
<%= select_tag :id , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
That gives your show action the proper resort id. You'll have to adjust that action to find the right activities relevant to the resort.

How to access associated object id in ajax loaded form

Using Rails 3.2, how can I access the id of an associated object within an embedded form loaded by ajax?
For example, I have an object called Hotels. Each Hotel has_many Rooms. When I edit a Hotel I would like to add new Rooms to this Hotel using an ajax loaded new Rooms form on the Hotel edit page.
I started by creating all the ajax using jquery on the Rooms index page. Everything works great there, but I don't have a Hotel ID, so I present a Hotel selection dropdown box. Now, I would like to add a new Room directly on the Hotel edit page. I don't understand how to pass the Hotel ID (#hotel.id) to the new ajax loaded Room _form.html.erb partial. On the _form.html.erb partial, I have:
<% if defined?(#hotel.id) %>
<%= f.hidden_field :hotel_id, :value => #hotel.id %>
<% else %>
<%= f.collection_select(:hotel_id, Hotel.all, :id, :name) %>
<% end %>
On the Hotel edit page, I have a link to add a new Room:
<%= link_to 'Add a Room', new_room_path, :remote=>true, :class => 'new_room' %>
And in my rooms_controller.rb I have:
# GET /rooms/new
# GET /rooms/new.json
def new
#room = Room.new
render :partial => 'form', :locals => { :room => #room }
end
How can I get the associated #hotel.id inside my ajax loaded new Room _form.html.erb partial?

going against REST conventions in Rails forms

Let me be clearer.
my app has two tables/models: Bikes and Cars
I have a form on page views/cars/index
However, even though the form is in views/cars/index, it has attributes (:pedals and :handlebars) for the Bikes table.
1) Which controller should the form on cars/index with attributes for the Bikes model be submitted to ?
2) What does the form have to look like (in terms of submitting from a view in the Cars index to Bikes model? <%= form_for(#car) do |f| %> OR <%= form_for(#bike) do |f| %>
3) What changes do I have to make to the route when I submit from the index of views/cars/index to insert data into the bikes table? why did I get a missing controller error message when I tried the solution posted by #axsuul
below this line is an earlier (maybe less clear) attempt to explain the problem but i don't think it was clear
this is a form that I have in views/cars/new.html.erb
<%= form_for(#car) do |f| %>
<% if #car.errors.any? %>
and the results are visible in views/cars/show and views/cars/index
However, if I want to submit a form from views/cars/index (Yes I know you don't usually submit from index), and then have it show in a completely different model views/bikes/index, what do I have to change to this?
<%= form_for(#car) do |f| %>
<% if #car.errors.any? %>
If i understand your question right you have a form for creating bikes on your cars/index page.
In that case, create a new bike in the cars controllers index action,
class CarsController < ApplicationController
...
def index
#cars = Car.all
#bike = Bike.new
end
...
end
and use that to create the form,
<%= form_for(#bike) do |f| %>
...
which left like that will be handled by bikes controllers create action.
I still consider this RESTful...
You can choose whatever URL you want to submit to by doing
<%= form_for(#car), :url => create_car_path do |f| %>
for the route
post '/views/cars/index', "cars#index", :as => :create_car
If you are asking to customize which view to render after submitting, you do that in the controller
def index
#car = Car.new(params[:car])
if #car.save
render 'bikes/index'
end
end
Hmm, so from what you explained, you are probably looking for something along the lines of
bikes_controller.rb
def create
#bike = Bike.new(params[:bike])
if #bike.save
redirect_to cars_path and return # this should go back to /cars if successful
end
render 'cars/index' # or render /views/cars/index.html.erb
end
cars_controller.rb
def index
#bike = Bike.new
end
index.html.erb
<%= form_for #bike, :url => create_bike_path do |f| %>
routes.rb
get 'cars' => "cars#index", :as => :cars
post 'cars' => "bikes#create", :as => :create_bike

RoR+ in rjs add value from prompt to table

in js.rjs file i am shwoing prompt with textbox like
page << "var name = prompt('Enter name:'); "
i want to add the value name to the table names
is it possible to do from rjs
if so please guide me how to do it..
You shouldn't do this back and forwarding with rjs. You're returning javascript to be executed by the client, and you can't get the value back directly unless you embed another AJAX call into the javascript your return.
A better way to do this would be to use a single AJAX call. Use a remote_form_for with a text_field for the user to enter their name into, then POST it to your controller action and store it in the database in the normal fashion.
Something like:
# In your view
<% remote_form_for :user, :url => { :controller => :users, :action => :create } do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
# In your controller
def create
#user = User.new(params[:user])
#user.save
render :update do |page|
# Return whatever javascript you want here
page << "alert('Created user')"
end
end

Resources