Let's say I have a UserProfileController#show
which renders a user's profile account page. The associated views and partials for this controller are under /app/views/user_profile/*
As with any UserProfile page, the user should be able to edit their preferences. This is done by clicking a preferences link which triggers the UserPreferences#show
and it displays a whole new page by rendering the views under /app/views/user_preferences/*
My current issue is that the latter page is a whole separate page that I have to link to. I'd love to instead be able to bring up the preferences page in a modal without leaving the user profile page. Or maybe I just want it embedded in the profile page itself at the bottom (ie it doesn't have to necessarily be a popup modal - wasn't looking for a specific answer to that).
The issue is that I have no way to call a whole new controller and action from my current UserProfileController
view. Is there a way to call this new route and have it generate the whole new page within my current page?
The only answer I've received so far is that I should consider doing it all from the same controller, but that's really overloading the UserProfileController
and my action method is becoming long and messy.
Thanks!
You're thinking about it wrong; you're not dealing with "pages" but controller
actions and views
. Subtle but important difference:
Rails itself is an MVC ( M odel V iew C ontroller) framework. It's not unique in this sense, but since many Rails devs don't have experience elsewhere, they have to learn the "mindset" of MVC first hand.
As you can see above, you can't simply render a "page" and see all the data you need. You need to populate the view with data (done in the controller), allowing Rails to send the relevant HTML etc in the browser.
Thus, you have to ask yourself how you're going to:
user_preferences
view The feature you'll probably need is partials .
Partials allow you to call a "sub view" in a main view. You have to provide the data for it etc, but it means you can render things such as menus and profiles inside other views, reusing the same code each time ( DRY - Don't Repeat Yourself ).
Partials are simple to create - just prepend an underscore to their name:
#app/views/user_preferences/_menu.html.erb
This is a user preferences partial.
You can call this in any view but make sure you have the correct data supplied!
Now, the important part is in how you invoke this partial:
#app/views/user_profile/index.html.erb
<%= render "user_preferences/menu", locals: {user: @user} %>
You'll be able to populate the @user
variable inside the Users
controller:
#app/views/user_profiles_controller.rb
class UserProfilesController < ActionController::Base
def index
@user = User.find x
end
end
--
The alternative is to use Ajax and download the entire user_preferences
view on demand. I would not recommend this for this instance.
Ajax basically sends an asynchronous (parallel) request to the server from your browser. The response received is then appended to the page. It's used to provide snippets of functionality (loading user data etc).
Ajax uses Javascript, and would have to be done like this:
#app/assets/javascripts/application.js
$(".some_button").on("click", function() {
$.ajax({
url: "path/to/user_preferences",
success: function(data) { // do something here }
});
});
As your question suggested you do have both the controller associated with user and on that page you can easily get user
object.
So you should use your userprofile controller's show action to get information of userprofile only. And in show view you should have some div which trigger ajax call on page load like below:
#show.html.erb
.....your user profile html....
<div id="user_prefrences" data-id="#{@user.id}"></div>
.....your user profile html....
And following changes in you js file.
$(function(){
var id = $('#user_prefrences').attr('data-id') ## get user id here
$.ajax({
url: '/user_prefrences/' + id,
success: function(result){
$("#user_prefrences").html(result);
}
});
});
In your controller remember to check for ajax request and send data without layout.
## UserPrefrences Controller
def show
if request.xhr?
....
layout false
else
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.