rails insert ajax via jquery - ajax

Good day!
I'm trying to implement ajax in my rails test app.
my controller code app/controllers/admin/data
class Admin::DataController < ApplicationController
...
def ajax
if params[:ajax] == 'list'
#responce = Admin::Datum.all
else
#responce ={error: true}
end
respond_to do |format|
# format.html { redirect_to #user }
# format.js
format.json { render json: #responce }
end
end
end
index.js.erb
alert('1');
$.post('/admin/data/ajax',{ajax:'list'},function(responce){
alert('2');
console.log(responce);
}
);
could you help me in determining the url that i've to use in ajax to access ajax method?
or any other help is very welcome!
Update 1
Updated initial code to represent more complex problem

I added to routes.rb
match 'admin/data/ajax' => 'Admin::Data#ajax'
could be any url, it's what you write in your jquery.
And it works!

Related

Update multiple files upload with CarrierWave

I have implemented the "multiple file uploads" in my model just like explained in the documentation of CarrierWave and it's working just fine. My problem is that I can't get the model update working. When I try to add new files it removes the old ones. I'd like to keep both. Here is part of my model and controller:
class Album < ActiveRecord::Base
mount_uploaders :photos, PhotosUploader
end
class AlbumController < ApplicationController
def create
#album = Album.new(album_params)
if #album.save
flash[:success] = 'Album created'
redirect_to #album
else
render 'new'
end
end
def update
#album = Album.find(params[:id])
if #album.update_attributes(album_params)
flash[:success] = 'Album created'
redirect_to #album
else
render 'edit'
end
end
private
def album_params
params.require(:album).permit({ photos: [] })
end
end
I thought about putting the photos in a different model but if I could make it work this way would be better. Any suggestions?
I have the below in my update method to ensure existing images (avatars) uploaded by CarrierWave remain in tact. I have a separate method that allows users to individually delete images.
def update
project_params_holder = project_params
project_params_holder[:avatars] += #project.avatars if project_params_holder[:avatars]
respond_to do |format|
if #project.update(project_params_holder)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end

Rails: Submitting an array of child elements

I'm trying to submit a form which is supposed to have an array of child elements. I'm not sure if I have it correctly. Can somebody help me refactor?
I have a couple of models user and item. A userhas_many :items.
The form that sends the information for user and items look like the following -
<%= form_for(#user) do |f| %>
<% f.text_field :name %>
<% f.fields_for :items do |item| %>
<% item.text_field :name %>
<% item.text_field :price %>
<% end %>
<% end %>
I have the following in my controller -
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
#items = #user.items.build(item_params)
if #items.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
end
format.html { redirect_to #user, notice: 'User was successfully created. But there was a problem saving the items.' }
else
format.html { render action: 'new' }
format.json { render json: #userd.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:name)
end
def item_params
params.require(:user).require(:item).permit(:name, :price)
end
When I save the user, only 1 record of items get saved, meaning - the data isn't being passed as an array of objects. How do I get this to work?
It looks like right now you are only ever telling Rails to build one item object. Your form is passing up the two parameters for an item, and in your controller you call build once, so #items is only ever set equal to the single Item returned by build. Unless their are hidden parts of your form you aren't showing, it looks like you're only setting one set of options for a user's items. If your goal is to have an array of many items with identical parameters, the fastest fix would be to just do this within the logic of your create action. There are many ways you could implement that (here is one simple way):
#items = []
x.times { #items << #user.items.build(item_params) }
If you're looking to send a request from the form with multiple unique items, you'll have to add more fields to your form, since currently you are only sending one set of parameters.
There are few corrections to be made in your code.
In your users_controller
def new
#user = User.new
3.times do #this will generate three records of items
#user.items.build
end
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
else
format.html { render action: 'new' }
format.json { render json: #userd.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:name,items_attributes: [:name,price])
end

Ruby render partial on form submit on same page

I am trying to render a partial that I made on top of the current page after a form submit. This should happen in the controller's create method, but I can't seem to figure out if this can be done in Ruby, or if I should just render it using Javascript.
Here is what I have tried so far:
Created a partial in the same folder as the new.html.erb (called _lightbox.html.erb)
The controller render changed to this:
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
BackgroundJob.perform_async(#user.id)
format.html { render :partial=>"lightbox", :layout=>false}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I have read up on render, however using the :partial key it simply renders the partial on a new page. I should probably just change the form to use :remote and add the lightbox-esque content with an ajax success, however I was curious as to if this can be done with Ruby on Rails with its rendering functionality.
The code you've displayed here isn't really the problem. It's all in the view.
You need to prevent the default action from form submission, which is to post to the form URL. If the browser posts to that URL, it will render the response. Once you've prevented the default action, you'll then need to submit the form yourself using javascript and set up a callback to deal with the response. That callback should put the html in the place you want it in the page. If any parts of this are unclear, I can expand upon them.

How to redirect using custom format routes in Rails?

I'm working on a simple app that requires me to redirect to a show action after the update action.
I have this route for show.
match '/user/:fullname' => 'items#show'
Which gives me this controller.
#user = User.find_by_fullname(params[:fullname])
However, after the update method of user,
def update
if #user.update_attributes(params[:user])
format.html { redirect_to #user } # Don't need to pass parameters here.
else
format.html { render action: 'edit' }
end
end
It redirects me to the original format of show action which is:
sampleapp.dev/users/1
How can I redirect to show action using the format I specified in the routes.rb which is by fullname?
sampleapp.dev/users/johndoe
Change this line to:
match '/user/:fullname' => 'items#show', :as => :custom_show_item
then change your redirect to:
redirect_to custom_show_item_path(:fullname => #user.fullname)

Best practice for Rails controller that paginates one mime format but not another

My rails project is paginating the HTML format but not the the others. Can someone suggest a more elegant approach to dealing with the difference in getting the #contacts collection? Perhaps the pagination version should be a different method that only supports HTML?
def index
if request.format.to_sym == :html
#contacts = Contact.paginate(page: params[:page]).search(params[:search])
else
#contacts = Contact.search(params[:search])
end
respond_to do |format|
format.html { render html: #contacts }
format.mobile { render mobile: #contacts }
format.json { render json: #contacts }
format.xml { render xml: #contacts.to_xml }
end
end
My solution was to add paginate as a RESTful resource in routes.rb which automagically gives me the route helper method: paginate_contacts_path
resources :contacts do
collection do
get 'paginate'
end
end
and to have a separate paginate method in ContactsController
def index
#contacts = Contact.search(params[:search])
respond_to do |format|
format.html { render html: #contacts }
format.mobile { render mobile: #contacts }
format.json { render json: #contacts }
format.xml { render xml: #contacts.to_xml }
end
end
def paginate
#contacts = Contact.paginate(page: params[:page]).search(params[:search])
respond_to do |format|
format.html
end
end
Strongly prefer a separate method because this creates inconstancies and makes the piece less testable. Also you would, in for example documentation, need to create exceptions.
Another way is to handle this with some parameter. Now it suddenly (when you only change views) returns different data. That might look like an error for an unknown developer and might raise issues.
So don't do it magically, clear parameter or separate method.

Resources