Rails specify controller action - ruby-on-rails

I have a folder views/home that contains the initial screen for a Rails app.
For some users, the home.index.html.erb displays a partial containing a list of workorkorders.
In other words I'm fetching a list of workorder and a list of worequests from the home/index.html.erb - therefore, I've added code to read the #workorders and #worequests into the home controller.
This is the code that fetches the workorders:
<% #workorders.notcompl.each do |workorder| %>
The home controller contains this code to fetch the workorders:
def index
#workorders = Workorder.all
I'd like to have _agentopenrequests.html.erb fetch all of the worequests.
So, I added the following to fetch the wore quests:
def index2
#worequests = Worequest.all
But, in the partial thats executed from home/index.html.erb file, how do get the following line to use index2 instead of index?
<% #worequests.notcompl.each do |worequest| %>
Should I put both #worequests and #workorders into index?
UPDATE1
I tried changing the home controller to this:
def index
#workorders = Workorder.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: Workorders3Datatable.new(view_context) }
end
#worequests = Worequest.all
respond_to do |format|
format.html # index.html.erb
end
end
But, I get
DoubleRenderError - Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action.
UPDATE2
Would it make more sense to have the partial in the worequests folder instead of home - so, the worequests controller gets used?

If all index2 does is pull a collection of worequests, you can copy/move it to the index action.

Related

Ruby on Rails 6. Using Ajax after redirection

Say, I have users list on the '/users' page and 2 actions for the 'user' entity: 'index' (with using of Ajax) and 'destroy'.
def index
...
respond_to do |format|
format.html
format.js
end
end
def destroy
...
redirect_to users_url
end
I want to destroy a user (right from the '/users' page) and use Ajax of the 'index' action after that ('index.js.erb' file) in order to render only a part of the opened '/users' page.
Is it possible to do that?
My current solution right now is to use Ajax for 'destroy' action (a separate 'destroy.js.erb' file) and duplicate needed changes for 'index' page there. But, first of all, it's a code duplication, and second, in this case my pagination links are broken (I use 'Kaminari' gem and looks like it works fine only with 'get' requests, at least by default).
There is a 'view' part of updating with Ajax, if necessary:
<div id="users_table">
<table class="table table-hover table-borderless">
...
<tbody>
<%= render #users %>
</tbody>
</table>
<div><%= paginate #users, remote: true %></div>
</div>
If you want the destroy action to render the index.js.erb:
def destroy
...
respond_to do |format|
format.js { render action: :index}
format.html { redirect_to users_url}
end
end
But, to render index.js you will need to, in your destroy action, rebuild the #users object and ensure you're rebuilding it for the correct page. So, when you call the destroy action you'll need to pass the ID(s) of the user(s) you want to destroy, as well as the page you are on.
Your destroy.js.erb should (on successful destruction) remove the destroyed element from the index by deleting a part of the HTML. I don’t expect that the code to do that duplicates the code you have in the index view.
Post your current destroy.js.erb as well as the relevant part of index.html.erb for more help though.
You can also use redirect within a respond_to so your HTML call will redirect while the Ajax uses destroy.js.erb
respond_to do |format|
format.js
format.html { redirect_to users_url}
You could also hack your way to your answer by calling render :index for the js response. But, if you were to try to render the index view here you’ll definitely get duplication of code, along with an extra DB call and probably some broken pagination. So, I’d recommend that you take the approach I first suggested (use destroy.js.erb to remove that user from the HTML)
Finally, more generally, when you’re trying to avoid duplication of view code; a partial might be the answer

dynamic content in ajax while rendering partial views

How do I get dynamic content when user clicks on different links?
views/dashboard/index.html.haml
.container
- #trips.each do |trip|
= link_to trip.id, quick_view_trips_path, remote: true
I'm pretty sure the quick_view_trips_path is incorrect as all the links are this:
1
13
51
Somehow I need to make these links dynamic, and then when user clicks on it, the modal window would be dynamic too.
If I replace quick_view_trips_path with just trip
= link_to trip.id, trip, remote: true
Nothing happens, and the url changes to the correct url, but my modal window doesn't get rendered through ajax. Here's an example of what the url looks like now:
1
In addition to what I'm trying to accomplish with dynamic content, is there a way to maybe change my url like so:
1
Is it possible to get ?quick_view=on appending to end of URL and make everything work again?
Here are the rest of my code:
views/trips/quick_view.js.erb
$('body').append('<%= j render partial: "trips/quick_view" %>');
views/trips/_quick_view.html.haml
.root-container
= #trip.title
= #trip.image
= #trip.more_details
This doesn't work either right now, as my application returns undefined method
routes.rb
resources :trips do
collection do
get 'quick_view'
end
end
trips_controller.rb
def quick_view
respond_to do |format|
format.html # quick_view.html.erb
format.js # quick_view.js.erb
format.json { render json: #trip }
end
end
Do I need to add anything to this controller as well to ensure the correct content will be generated through the partial?
How about this way,
Path
link_to trip.id, quick_view_trips_path(:js, trip_id: trip.id), remote: true
This will render, 1
Controller
def quick_view
#trip = Trip.find(params[:trip_id])
respond_to do |format|
format.html # quick_view.html.erb
format.js # quick_view.js.erb
format.json { render json: #trip }
end
end
It will respond views/trips/quick_view.js.erb file

Rails partial how to use controller function

With a Rails index view, you can create a matching controller action. For instance a view called workorders.index2.html.erb,can have the following controller action:
class WorkordersController < ApplicationController
def index2
#workorders = Workorder.order("position")
respond_to do |format|
format.html # index.html.erb
format.json { render json: #workorders }
end
end
But, what if you have a partial called _mygroupswos.html.erb. How can I get the partial to use a matching action in the workorders controller?
Thanks for the help!
Rails Controller renders the view automatically based on the naming convention. But you can always override it by asking the action to render a different view explicitly.
def some_action
render :partial => "mygroupswos", :layout => true
end
partials are generally used for sharing view logic. So I would advice you to create a view template and render the partial there.

Showing Post + Poster's Info on the "Index" Page

I want to show a post along with the poster's info on my rails app. Right now I'm able to show the post and user association on the "show" page (the page for a single post), but when I want to show it on the "index" page (where all of my posts are), I get this error: undefined method `username' for nil:NilClass
I added #post.user = current_user to my post_controller under "show" (That allowed me to show the poster's info. But i dont know what to add to the "def index".
This is what I have there:
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
This is what I have under "show"
def show
#post = Post.find(params[:id])
#post.user = current_user
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
I want to know what to add to my def index to be able to display the poster's info. Thanks in advance.
Your set up is wrong. The user needs to be added to the post when it is created and updated.
As you have it now, all posts will always belong to the user that is currently viewing the post because you are assigning the current_user to the post in the show action (and would be doing the same in the index view if you continued with this approach) meaning that when post 1 is viewed by user 1 it would show as belonging to user 1. When post 1 is shown by user 2 it would belong to user 2.
The solution is to assign the current user to the post in the update and create actions of the posts controller exactly as you have it now in the show action but before the post gets physically updated or created.
Then remove the #post.user = current_user from the show action.
This may mean you are left with legacy data in your app that doesn't have a user assigned. But that's o.k., just edit and save each post and it will have you attached automatically.
Then in the views/posts/index_html.erb just add the user details that you want to see in new table row columns before the show/edit links. This is assuming you have a standard scaffolded index.html.erb file. If you don't have a standard index view then put it wherever you want it but then if you had a customised index view you probably wouldn't be asking this question in the first place so forget about that and you'd know where it goes
Update
I did explain how to show the user in the views in my response above but possibly I need to be a little clearer so I'll show you the code.
To show the user name in the show view use
<%= #post.user.name unless #product.user.blank? %>
To show the user in the index action for the post use
<% #posts.each do |post| %> <!-- This is already in your index action. -->
<%=post.user.name unless post.user.blank?%><!-- This is the code you need -->
<!-- You might want to add a new th in the header for the css table then you can add a <td></td> tags round the above line so your table all matches up nicely for display purposes-->
<%end%> <!-- This is already in your index action -->
Hope that helps

rails reusing view templates

A rails newbie here
I have 2 actions in my controller 1) index 2) refine_existing.
Both of them show the results in the same format.
How do I reuse the index.html.erb file?
When I try the following, it complains about refine_existing.erb not being present.
def refine_existing
...
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
my index action looks like this
def index
#some logic to get #results
#set some session variables etc.
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
Do I have to refactor my index view to contain partials that
a) make the headers
b) render #results
and reuse them?
Even though, both index.html.erb and refine_existing.html.erb will look exactly the same
Is there any way I can say in my refine_existing action to use index.erb view?
thanks in advance
By convention, if you don't specify a template name Rails looks for one matching the action. You can override this by calling render explicitly with the desired template name. The only wrinkle is that the path is relative to TEMPLATE_ROOT, which is normally app/views:
def refine_existing
...
respond_to do |format|
format.html { render :template => "<table_name>/index.html.erb" }
end
end
replacing table_name with the "tablized" form of the model. E.g. if your controller is PostsController, then posts. So your template would then live in app/views/posts/index.html.erb -- if you've customized paths somehow adjust as necessary.

Resources