Reputation: 43
I would like to have my user click a 'Bio' link located in their Profile Page that will display their bio contents pulled from the database. For this I have created a partial lovelies/_bio.html.erb because i would like to load the 'user bio' on their 'Profile Page' and not send them off to another page.
Presently, the partial is unable to be found. This is my code below.
In my routes.rb file, i have created a url path for the bio action which translates to
bio_lovely_path url -> /lovelies/:id/bio
This is done in this manner since i need to retrieve that particular user's information i created it as a member.
config/routes.rb
resources :lovelies do
member do
get 'bio'
end
end
My link is in my layouts/_header.html.erb
if logged_in?
<li class="header-log"><%= link_to "Bio", bio_lovely_path, :remote => true %></li>
else
//display none logged in links
<%end%>
My controller where I have the action is called
LovelyController, the bio action is defined as follows
//display the current user bio
def bio
@lovely = Lovely.find(params[:id])
respond_to |format|
format.js
end
end
I have a jQuery call in my lovelies.coffee file to render the lovelies/_bio.html.erb partial to the div in my lovelies/show.html.erb
jQuery ->$('#partial).html '<%= escape_javascript(render 'bio') %>
My output says throws a 500 error - Failed to load resource.
My understanding is that the jQuery adds that html to the <div>
in show.html.erb which process it as ruby and should result in the _bio.html.erb being rendered.
I am new to Rails and would really appreciate suggestions and guidance on how to go about solving this issue.
Thanks
Upvotes: 3
Views: 5493
Reputation: 43
Found a simple solution
html file - //button to click and display bio on the page
<button id="display-bio">Lovely Bio </button>
//the div which displays the bio on the page
<div id="bio" style='display:none'>
<%= render 'layouts/bio'%>
</div>
code in coffeescript
//the code in coffee script to trigger the event
$('#display-bio).click ->
$('#bio).show()
I think that's pretty simple.
Upvotes: 1
Reputation: 725
It sounds like what you are trying to do is make an AJAX call in Rails, judging from the :remote => true
in the link helper. You are almost there; however, you aren't quite doing what Rails expects.
When a link that looks like this
= link_to 'Bio', bio_lovely_path(@lovely), :remote => true
# small change from the code you gave - because your path `lovelies/:id/bio`
# has `:id` in it, you must provide the object you are referring to, `@lovely`.
# in fact, this is probably where your 500 error came from.
is clicked, it's as though it triggers an AJAX call like so:
// you don't have to write this; `:remote => true` ensures that it gets done
// for you.
$.ajax({
url: '/lovelies/<@lovely.id>/bio',
type: 'get',
dataType: 'script'
})
This hits your lovelies#bio
controller action as data type js
. You did the right thing there by telling it to respond_to
the js
format. This will allow it to render a js
file. That is, at the end of the controller action, Rails will look for a corresponding js.erb
file to execute. (Usually, it looks for a html.erb
file, but you have, by using :remote => true
, told it to use JavaScript this time.)
app/views/lovelies/bio.js.erb1
$('#partial').html('<%= escape_javascript(render(partial: "bio.html.erb")).html_safe %>');
Formerly, you had approximately this code in lovelies.coffee
, which won't work. For one, Rails won't know to execute it after the controller action. For another, files in your assets
folder are limited in their ERB capabilities (though they can do a little, if you give them the .erb
extension).
1 You can use CoffeeScript, .coffee.erb
, if you prefer. I don't know the specifics of that, though; I avoid CoffeeScript when I can.
Now that I've attempted to explain the AJAX process when using the Rails :remote => true
attribute, let me propose an alternative. I've recently recognized that for a task as simple as inserting a few more elements into a page, it's usually easier to just include them in the first place. Hide them by giving their container the display: none
CSS property, and then reveal them when the button is clicked with jQuery's .slideDown()
or something similar. It will let you skip the routing, controller action, js.erb
file, and all that hassle.
Basically, I'd recommend to (most of the time) save the fancy AJAX calls in Rails for when you need to delete, create, or update. It isn't usually worth it for dynamically adding a little extra information to the page when there's a simpler way.
Upvotes: 3
Reputation: 14949
A partial is supposed to be rendered as part of a different page using render partial: 'name_of_partial'
within another file. However, your controller has a bio
method, which will need a bio.html.erb
file for rails to use for the main bio page at that path. Note the lack of an underscore at the start of the filename.
Either use a different page and render your _bio.html.erb
partial within it (and don't have a separate path), or have a page that's just for the bio.
Upvotes: 1