Ruby on Rails remote create form with popup show partial - ruby-on-rails

I'm a RoR junior and I'm making online shop app, so:
on the show view of product I have remote form for #line_item
in the show action of products_controller I have #line_item = LineItem.new
I have create.js.erb file in views/line_items
My create action of line_items_controller looks like this:
respond_to do |format|
format.js { }
end
QUESTION: How to make a popup window with line_item's details information appearing when line item's create form is submitted?

You don't need that line in the controller there - all you need is to trigger the display of a popup inside your create.js.erb. That js file will be rendered by convention after executing the create controller method because it is an asynchronous call.

Related

How are these to rails functions connected?

I am following this tutorial: Youtube rails tutorial
He is creating a basic website where people can add books, review them, rate them, delete them and so on. In the main controller script, he defines a function "new" to add a new book like so:
def new
#book = Book.new
end
def create
#book = Book.new(book_params)
if #book.save
redirect_to root_path
else
render 'new'
end
end
def book_params
params.require(:book).permit(:title, :description, :author)
end
He also uses a creat function for that. He has a "new" view named new.html.erb that actually shows the form where users can add a new book and this is related to the "new" function shown in the controller. The new.html.erb file only has this:
<h1>new book</h1>
<%= render "form" %>
I get most of it, what I don't get is, since the "new" function doesn't do anything and the "create" function is the one doing all the work for the "new" function, how are they related? I am asking this because the "new" function does not "call" the create function at all but the work the "create" function does is shown in the webpage. Are they connected through "#book"?
new action renders new.html.erb, which contains a form to create a new book. When a user clicks submit on that form, that new book is created with the create action.
I will recommend going to more tutorials and reading the guides to get a full understanding on how Rails works.
In Rails the new action displays the form for creating a resource.
create responds to when the user posts a form.
class BooksController < ApplicationController
# GET /books/new
def new
#book = Book.new
end
# POST /books
def create
#book = Book.new(book_params)
# ...
end
end
I am asking this because the "new" function does not "call" the create
function at all but the work the "create" function does is shown in
the webpage. Are they connected through "#book"?
You're fundamentally confused about how web applications and MVC work. Web applications respond to requests coming from a user. The server sends a a response and thats it. The program ends. The server does not sit around waiting for the user to click like a desktop program.*
They are not "connected" at all. new and create respond to a different kinds of requests at different paths. The are never both invoked in same request.
The new action shows and initialize the form. What you complete on it before you click on create button will send to the create action of the BooksController. This action will create a new Book object with the params, and save in DB.
This is MVC pattern. You should read about it: https://www.sitepoint.com/the-basics-of-mvc-in-rails-skinny-everything/

Can I override just part of an ActiveAdmin controller action using `super` + custom redirect?

I've registered a Widget in ActiveAdmin and want to change the redirect that takes place after creating a new one. So that I can accomplish various things with Javascript, I've created a custom form for creating/editing them such that in /admin/widget.rb I have this:
form do |f|
render "create_or_edit_widget"
end
I want to modify the basic Admin::WidgetsController#create action to change where the user is redirected after successfully creating one. I can fill out the rest of the custom action to complete this, except I don't know how to handle a case where the .save fails and the user is redirected back to the form with the formtastic inline error messages. I know how I could do this if I wanted the normal Rails form behavior of creating a list of error messages but not enough about Formtastic to copy its behavior. So far I have this:
controller do
def create
#widget = Widget.new(params[:widget])
if #widget.save
redirect_to admin_widgets_path, notice: "Successfully created Widget."
else
redirect_to :back
end
end
end
I was wondering if I can somehow user super and then only change the redirect path after successful creation instead of having to write out the entire action. If that's not possible, can anyone tell me where in the ActiveAdmin GitHub I'd be able to find the standard #create action so I can copy it out and change the one part?
Yes, you can do that. Here is a working code from my application using super and just changing the redirection
def create
super do |format|
redirect_to admin_submission_discussion_path(id: resource.discussion.slug, submission_id: resource.discussion.client_application.slug) and return if resource.valid?
end
end

Rails: Rendering partial in div on click

I'm building a webapp that features a UI split into two sides, a menu bar and a content area.
The menu bar has a listing of the titles of all blogs that a user has written. When a title is clicked, the content area should change to show the posts of that blog.
1.) So on my menu bar, I have:
<%= link_to blog.title, blog, :remote=>true %>
And in my content area, I have:
<div id="contenthere"></div>
2.) So by my understanding, this should trigger the show method of the blog controller. There, I have the following in the method:
#blog = Blog.find(params[:id])
respond_to do |format|
format.js { render :show_blog }
end
3.) Which should go look for a file called show_blog.js.erb in views/blogs folder:
$("#contenthere").html("<%=escape_javascript(render :partial=>"show_blog")%>");
Which will take my div with commenthere id and render the _show_blog.html.erb partial (located in the blog view folder) with the blog parameter equal to the #blog parameter that was set in my blog controller.
4.) So my show blog partial has this code:
<%=#blog.title %>
<%=#blog.user_id %>
EDIT: Actually, I search around and found out that I can't use the method 'render' from within the assets folder-- where do I put the js.erb then? I've moved it to the blog view folder, home view folder (index.html.erb), and just the /view/ folder... The error is gone, but the link is not working...
EDIT: Put the show_blog.js.erb in my views/blogs folder, since it's the blog controller calling it. Nothing happening when I click the link and no JS errors shown in console. Is the js being called at all?
EDIT: Changed to reflect my final answer.
#blog = Blog.find(params[:id])
respond_to do |format|
format.js { render :show_blog }
end
That is not Rails default logic.
You didn't provided, how method is called, suppose
def show_blog
#blog = Blog.find(params[:id])
respond_to do |format|
format.js
end
end
Then, Rails will look for show_blog.js.erb in views/blogs and render that file.
Also, you need to pass actual instance to partial, because patrial is stand-alone chunk of code and doesn't know, what #blog is:
$("#contenthere").append("<%=j render :partial=>"show_blog", :locals=>{:#blog=>#blog}%>");
Very simple solution in the end--- The partial was calling for blog.title, blog.user_id, but #blog was the actual param that was passed. Just had to change to #blog.title and #blog.user_id.

Rails : Is it possible to put a "create" form on a "index" or "show" view?

Hi I'm trying to work on my first rails project and was wondering if it was possible to combine the show or index view (of photo albums) with a form that creates more photo albums. Would the URL not have the correct parameters to do this? Would I be able to set the action on the form to make it "create" and redirect_to the index page again on success?
Sure you can do this, just put the form code on whatever page you want to create/update from and it will work.
The only issue is where the action would redirect you to after a successful or unsuccessful create/update: usually from the new page, you would redirect to the newly-created record (show action for the new record) on success and back to the new action on failure (with the errors on the form fields). If you want to create/update records from different pages, and have the action redirect to different pages in each case, then you'll have to do just a bit more work.
On possibility would be to add a hidden parameter to the form with the action to redirect to, and make the action check for it and redirect accordingly. For example:
VALID_REDIRECT_ACTIONS = ["show", "index"]
def create
...
if #photo.save
flash[:success] = "Photo successfully created!"
if VALID_REDIRECT_ACTIONS.include?(params[:redirect])
redirect_to params[:redirect]
else
redirect_to #photo
end
else
...
end
end

Calling methods that render views conditionally in a Rails Controller

I am writing a Ruby on Rails application with a controller called "pages_controller" that is responsible for displaying pages to users. There are 3 different types of pages that can be displayed, and different things have to happen on the back end in each case, so I decided to break the functionality out into 3 methods within the controller. When the user requests a page, the "show" method is called, which figures out whether the page:
1. Belongs to the user
2. Belongs to another user, and can be viewed by the user requesting it
3. Belongs to another user, and cannot be viewed by the user requesting it (unauthorized)
The appropriate method is then called from there to display the page. The code looks something like this:
def show
if (something)
showMine
elsif (something else)
showAnother
else
showUnauthorized
end
end
def showUnauthorized
respond_to do |format|
format.html # showUnauthorized.html.erb
end
end
def showMine
respond_to do |format|
format.html # showMine.html.erb
end
end
def showAnother
respond_to do |format|
format.html # showAnother.html.erb
end
end
I am getting a template missing error because rails wants to render a view when "show" is called, but I do not want any views to be rendered when "show" is called. I simply want "show" to call the correct method from there, and the corresponding view for that method (showMine, showAnother, or showUnauthorized) to be rendered. How can I do this? Or am I going about this the wrong way entirely?
You need to declare these new actions that you have created in the routes file, as they don't belong to the RESTful routes.
I sugest to keep only the show action in your controller and create the IFs in the show view using the render method to include the partials(_showMine.html.erb, showAnother.html.erb, showUnauthorized)
example:
show view:
if (something)
<%= render 'showMine' %>
elsif (something else)
<%= render 'showAnother' %>
else
<%= render 'showUnauthorized' %>
end
I hope it helps...
I basically agree with Samy's comment, but here's some background:
The method that tells Rails what view to use is render. If there's no call to that method in your show method, Rails assumes you have a view called show.xxx.xxx, e.g. show.html.erb, that is supposed to be rendered. Note that it doesn't assume template will be prefixed with show because that's the name of the method. It assumes it will be show because that's the name of the action. The name of the action is passed to the controller as part of the request; it's not simply derived from the name of whatever method has a respond_to block in it.
All the respond_to blocks do is specify different view templates based on the MIME type of the request, but since you never call render, all of those extra methods are still trying to call the show view (show.html.erb in every case), because you never told Rails to render any other view, and the action name is show.
So, instead of the respond_to blocks, just call render [some_view] in each of your other methods.
This might not be the clearest answer, but I'd suggest also reading the following:
http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/
It describes what respond_to does, in particular how it keys off the action name to determine what view to render.

Resources