Vous êtes sur la page 1sur 4

7.

Advance >
7.1. ajax in RoR
Work-flow
Description :
1. from browser, view requested with type js (especially used by click link or submit form).
2. in controller will automatic process the request from view as js. Then controller will render view with extension .js.erb.
3. from .js.erb, using js function will append partial page with extension .html.erb.
4. if page partial found it will render to the same page where request was sent.
Study case : for implementation ajax we will used in page show article page, so when user insert comment user will directly see list comment that current insert without
refresh all page only area that show list comment, but if save fails the error message will show in area form input (refresh only area form input).
First let modify method show in articles_controller.rb, add this :
def show
@article = Article.find_by_id(params[:id])
@comments = @article.comments.order("id desc")
@comment = Comment.new
end
- @comments , it will use by list data of comment in show view.
- @comment, it will create new object for create new comments.
Now lets setup view show article (views/articles/show.html.erb), add this :
<h3><%= @article.title %></h3>
<p><%= @article.content %></p>
<p><%= link_to 'back to index', articles_path %></p>
<div id="form-comment">
<%= render 'form' %>
</div>
<h4>Here the comments</h4>
<div id="list-comments">
<%= render 'comments' %>
</div>
- render 'form', is where partial view for input form comment is loaded (_form.html.erb).
- render 'comments, is where partial view for list data comment is show (_comments.html.erb).
Create new file to : views/articles/_form.html.erb, and add this :
<%= form_for @comment, url: comments_path, remote: true do |f| %>
<%= f.hidden_field :article_id, value: @article.id %>
https://sites.google.com/a/kiranatama.com/modul...
1 of 4 10/13/2014 07:44 PM
<% if current_user %>
<%= f.hidden_field :user_id, value: current_user.id %>
<% end %>
<br/>
<%= f.label :content %>
<%= f.text_area :content, cols: 20, rows: 10 %>
<br/>
<%= f.submit :submit %>
<% end %>
- @comment, is global variable that declared from action show in controller articles, use for create object new.
- remote: true, where you tell to controller comments the request type is js/ajax, so when you click button submit it won reload/refresh the current page.
Create new file to : views/articles/_comments.html.erb, and add this :
<% @comments.each do |comment| %>
<p>
<b><%= comment.user.try(:username) %></b>
<br />
<%= comment.content %>
</p>
<% end %>
- @comment, is global variable that declared from action show in controller articles, use for hold all data comment for specific article.
After setup view now we need setup default value for status and add validation to content of comment. Open model comment.rb, and add :
class Comment < ActiveRecord::Base
before_create :default_status
belongs_to :article
belongs_to :user
validates :content, presence: true, length: { minimum: 10 }
def default_status
self.status = "not active"
end
end
- default_status, is action that will set data to column status with value not active.
- validation :content, presence: true, is validation for input comment.
Lets add process to controller comments, open comments_controller.rb and modify into :
class CommentsController < ApplicationController
before_action :check_current_user, only: [:new, :create, :edit,
:update, :destroy]
def create
respond_to do |format|
@comment = Comment.new(params_comment)
if @comment.save
format.js {@comments = Article.find_by_id(params[:comment]
[:article_id]).comments.order("id desc")}
else
format.js {@article = Article.find_by_id(params[:comment]
[:article_id])}
https://sites.google.com/a/kiranatama.com/modul...
2 of 4 10/13/2014 07:44 PM
end
end
end
private
def params_comment
params.require(:comment).permit(:article_id, :user_id,
:content, :status)
end
end
- check_current_user, is used for make sure if want access action in controller must login first.
- response_to, is action for define type of response, in this case we use format.js that will render the page as js. So after success or fails saving data it will render page
create.js.erb.
- params_comment, is strong variable so you need manually add specific column that will insert to table.
Create new file to : views/comments/create.js.erb, and add this :
<% if @comment.errors.present? %>
$("#form-comment").html(" <%= j( render 'articles/form' ) %>");
$($(".field_with_errors")[0]).append("<p class = 'message'> <%=
escape_javascript( @comment.errors[:content].first ) %></p>");
<% else %>
$("#list-comments").html(" <%= j( render 'articles/comments' )
%>");
$("#comment_content").val('');
$("div.field_with_errors p.message").remove();
<% end %>
- @comment.errors.present, will check if error happens when create new comments.
- render 'article/form' and render 'article/comments', that will render the partial page from views/articles.
Now insert comment in page show articles, first we try the invalid input the result must be :
if data not valid it will show error notification, the input cannot be blank, now try insert the valid data, it will result :
https://sites.google.com/a/kiranatama.com/modul...
3 of 4 10/13/2014 07:44 PM
the content of comment will automatic show without refresh the page.
https://sites.google.com/a/kiranatama.com/modul...
4 of 4 10/13/2014 07:44 PM

Vous aimerez peut-être aussi