Reputation: 1761
I have a story model that has many posts. I list the stories in an index view without each story's posts. When a user clicks on one of the stories in the index view I want to load that story's posts via calling stories/(story_id)/posts using the ajax .load function, and make sure to put the posts into that story's correct div (created by "<%= div_for(story, "posts_bucket_for") do %>")
The problem is, I don't know how to pass the correct story_id to the .load function or how to make sure that the resulting posts are loaded into the correct posts_bucket_for.
Here's my _story.html.erb file:
<%= div_for(story) do %>
<%= div_for(story, "heading_for") do %>
<span class=story_title>
<%= story.title.titleize %>
</span>
<span class=story_post_amount>
# of posts: <%= story.posts.length %>
</span>
<% end %>
<%= div_for(story, "posts_bucket_for") do %>
<% end %>
Here's my PostController#index action
def index
@story = Story.find(params[:story_id])
@posts = @story.posts
respond_with(@posts, :api_template => :public, :root => :posts)
end
Any help would be greatly appreciated!!!
Upvotes: 1
Views: 1117
Reputation: 719
There are many ways of doing what you are trying to achieve and, I bet, many of the contributors here will give you a solution based on their coding experience. Here is mine:
First and foremost, you must decide if you need to keep the story title visible or not once you "upload" the actual story to the point you want.
I have no idea about ruby or ruby-on-rails but have a very good track on "blogging".
Let's say that from your database you listed the stories available as
<div id='story1' onClick='showStory(1); ' >Story 1</div>
<div id='story2' onClick='showStory(2); ' >Story 2</div>
<div id='story3' onClick='showStory(3); ' >Story 3</div>
<div id='story4' onClick='showStory(n); ' >Story n</div>
function showStory(storyNumber) {
$.get('url-of-the-story-storyNumber', function (data) {
$('#story'+storyNumber).html(data);
});
}
or
function showStory(storyNumber) {
$('#story'+storyNumber).load('url-of-the-story-storyNumber');
}
If you plan on not overwriting the story title line, you just drop another div into the story line:
<div onClick='showStory(1); ' >
Story 1
<div id='story1' ></div>
</div>
<div onClick='showStory(2); ' >
Story 2
<div id='story2' ></div>
</div>
<div onClick='showStory(3); ' >
Story 3
<div id='story3' ></div>
</div>
<div onClick='showStory(n); ' >
Story n
<div id='storyn' ></div>
</div>
The easier you make your IDs "manageable" the easier will be to make manuevers with them.
Good luck!
Upvotes: 2
Reputation: 4041
Here is one way to implement a solution (this is for Rails 3).
According to the Rails documentation for div_for
, div_for(story, :class => "story")
will produce HTML that looks like:
<div id="story_123" class="story"> Your content </div>
So, with jQuery, you could run something like:
// Attach click event handlers to your story divs
$(function() {
$("div.story").click(function() {
// Get the HTML ID of the story div
html_id = $(this).attr('id');
// Extract the database id
story_id = html_id.split("_")[1];
// Call your handy function to load story posts
loadStoryPosts(story_id);
});
});
For your buckets, I would not use another div_for(story)
. This would result in you having two divs
on the page with the same ID. Instead, I would do something like this:
<%= div_for(story, :class => "story") do %>
<p>The story</p>
<div class="posts" />
<% end %>
And then, in jQuery
// Make an AJAX request to your Rails server
function loadStoryPosts(story_id) {
// This is a jQuery AJAX GET request to your stories/:id/posts route
$.get("stories/" + story_id + "/posts", function(data) {
html_id = "story_" + story_id;
// Insert the result of the request into the appropriate posts bucket
$("#"+html_id+" .posts").html(data);
});
}
The remaining task is to have a controller action handle the AJAX request and return the posts to be inserted onto the page.
class StoriesController < ApplicationController
def posts
story = Story.find params[:id]
# Render the story's posts inside a partial (without any layout)
render :partial => "stories/posts", :locals => { :posts => story.posts }, :layout => false
end
end
You'll also want to create a partial to render the posts. In my example, this would be views/stories/_posts.html.erb
.
This is a lot of new learning material if you haven't dealt with AJAX+Rails before, so here are a couple useful tutorials: here and here.
Upvotes: 0