Kamis, 18 September 2014

Membuat Aplikasi POS dengan Ruby on Rails 4 part 2

Pada post sebelumnya  kita sudah mengerjakan desain dan model aplikasi, sekarang kita akan lanjutkan ke fungsi dan  bagian yang belum lengkapnya.

Fungsi Generate Code

Product mempunyai attribut code dan codenya nanti akan di generate secara otomatis.
Attribut ini nantinya bisa digunakan untuk barcode.
  1. Pada folder view/productIndex dan formnya dirubah
  2. File _form.html.erb bagian user dan codenya di hilangkan 
  3.  <%= form_for(@product) do |f| %>  
      <% if @product.errors.any? %>  
       <div id="error_explanation">  
        <h2><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h2>  
        <ul>  
        <% @product.errors.full_messages.each do |message| %>  
         <li><%= message %></li>  
        <% end %>  
        </ul>  
       </div>  
      <% end %>  
      <div class="field">  
       <%= f.label :name %><br>  
       <%= f.text_field :name %>  
      </div>  
      <div class="field">  
       <%= f.label :price %><br>  
       <%= f.text_field :price %>  
      </div>  
      <div class="actions">  
       <%= f.submit %>  
      </div>  
     <% end %>  
    
  4. Untuk index.html.erb codenya seperti berikut
  5.  <h1>Listing Product</h1>  
     <table class="table table-striped">  
      <thead>  
       <tr>  
        <th>Name</th>  
        <th>Code</th>  
        <th>Price</th>  
        <th></th>  
        <th colspan="3"></th>  
       </tr>  
      </thead>  
      <tbody>  
       <% @products.each do |product| %>  
        <tr>  
         <td><%= product.name %></td>  
         <td><%= product.code %></td>  
         <td><%= product.price %></td>  
         <td><%= link_to 'Show', product %></td>  
         <td><%= link_to 'Edit', edit_product_path(product) %></td>  
         <td>  
           <%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %>  
         </td>  
        </tr>  
       <% end %>  
      </tbody>  
     </table>  
     <br>  
     <%= link_to 'New Product', new_product_path %>  
    
  6. Tambahkan code pada model product
  7.   before_create :set_code  
      def generate_code(size = 6)  
       charset = %w{ 2 3 4 6 7 9 A C D E F G H J K M N P Q R T V W X Y Z}  
       (0...size).map{ charset.to_a[rand(charset.size)] }.join  
      end  
      def set_code  
       self.code = generate_code(6)  
      end  
    
  8. Selanjutnya di controller productnya  tambahkan baris berikut pada method create
  9.  @product = Product.new(product_params)   
     @product.user_id = current_user.id #tambahkan code ini setelah code diatas  
    
  10. Lakukan input data di url http://localhost:3000/products/new

Membuat Nested Form 

  1. Edit model sale.rb tambahkan code berikut
  2.  has_many :items  
     accepts_nested_attributes_for :items, allow_destroy: true  
    
  3. Edit partial _form.html.erb di dalam folder view/sales
  4.  <%= form_for(@sale) do |f| %>  
      <% if @sale.errors.any? %>  
       <div id="error_explanation">  
        <h2><%= pluralize(@sale.errors.count, "error") %> prohibited this sale from being saved:</h2>  
        <ul>  
        <% @sale.errors.full_messages.each do |message| %>  
         <li><%= message %></li>  
        <% end %>  
        </ul>  
       </div>  
      <% end %>  
      <div class="field">  
       <%= f.label :name %><br>  
       <%= f.text_field :name %>  
      </div>  
      <%= f.fields_for :items do |builder| %>   
        <%= render 'item_fields', f: builder %>   
      <% end %>   
      <%= link_to_add_fields "Add Item", f, :items %>   
      <div class="actions">  
       <%= f.submit %>  
      </div>  
     <% end %>  
     <script type="text/javascript">   
      jQuery(function() {   
       $('form').on('click', '.remove_fields', function(event) {   
       $(this).prev('input[type=hidden]').val('1');   
       $(this).closest('fieldset').hide();   
       return event.preventDefault();   
       });   
       return $('form').on('click', '.add_fields', function(event) {   
       var regexp, time;   
       time = new Date().getTime();   
       regexp = new RegExp($(this).data('id'), 'g');   
       $(this).before($(this).data('fields').replace(regexp, time));   
       return event.preventDefault();   
       });   
      });   
      </script>   
    
  5. Edit aplication_helper.rb tambahkan code berikut
  6.   def link_to_add_fields(name, f, association)  
       new_object = f.object.send(association).klass.new  
       id = new_object.object_id  
       fields = f.fields_for(association, new_object, child_index: id) do |builder|  
        render(association.to_s.singularize + "_fields", f: builder)  
       end  
       link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})  
      end 
    
  7. buat file partial _item_fields.html.erb di folder sales/app/views/sales/ isinya seperti berikut
  8.  <fieldset>  
      <%= f.label :product, "Product" %>  
      <%= f.collection_select :product_id, Product.all, :id, :name %>  
      <%= f.label :quantity, "Quantity" %>  
      <%= f.text_field :quantity, class: 'padli' %>  
      <%= f.hidden_field :_destroy %>  
      <%= link_to "remove", '#', class: "remove_fields" %>  
     </fieldset>  
    
  9. Periksa di http://localhost:3000/sales/new hasilnya akan seperti gambar berikut

Fungsi Hitung Penjualan 

Tadikan di form penjualan kita sudah bisa input item dan jumlahnya,  tapi total penjualanya belum terhitung. Nah sekarang kita akan buat menghitung total nya:
  1. Edit model item ketikan code berikut:
  2.   before_save :set_total  
      def set_total  
       if self.quantity.blank?  
        0  
       else  
            self.total = self.quantity * self.product.price  
       end  
      end  
      def subtotal  
       if self.quantity.blank?  
        0  
       else  
            self.quantity * self.product.price  
       end  
      end  
    
  3. Edit model sale untuk menghitung total harga penjualan berikut codenya
  4.   def subtotals  
       self.items.map { |i| i.subtotal }  
      end  
      def total_all  
       subtotals.sum  
      end  
    
  5. Edit controllers sales_controller.rb
  6. Tambahkan pada method create code berikut
  7.  @sale = Sale.new(sale_params)  
     @sale.user_id = current_user.id #tambahkan ini setelah code di atas  
     @sale.total = @sale.total_all #tambahkan ini setelah code di atas  
    
  8. Tambahkan parameter yang akan di permit
  9.  params.require(:sale).permit(:name, items_attributes: [:id,:product_id, :price,:quantity,:total,:_destroy])  
    
  10. Lakukan input data penjualan  http://localhost:3000/sales/new tambahkan beberapa item kemudian simpan
  11. Periksa apakah total penjualanya terhitung
  12. Edit file show di folder view sale
  13.  <p id="notice"><%= notice %></p>  
     <p>  
      <strong>Name:</strong>  
      <%= @sale.name %>  
     </p>  
     <%= link_to 'Edit', edit_sale_path(@sale) %> |  
     <%= link_to 'Back', sales_path %>  
     <h1>Listing Item</h1>  
     <table class="table table-striped">  
      <thead>  
       <tr>  
        <th>Product</th>  
        <th>price</th>  
        <th>quantity</th>  
        <th>total</th>  
        <th></th>  
       </tr>  
      </thead>  
      <tbody>  
       <% @sale.items.each do |item| %>  
        <tr>  
         <td><%= item.product.name %></td>  
         <td><%= item.product.price %></td>  
         <td><%= item.quantity %></td>  
         <td><%= item.total %></td>  
        </tr>  
       <% end %>  
      </tbody>  
     </table>  
     <hr>  
      <p> Total </p>  
      <%= @sale.total%>  
     <hr>  
    

Mengatur User-Roles

Pada bagian ini kita akan mengatur hak akses user pada aplikasi POS.
  1. Generate cancan
  2. $ rails g cancan:ability
  3. Tambahkan code di class ability.rb seperti berikut: 
  4.  class Ability  
      include CanCan::Ability  
      def initialize(user)  
       if user.present?  
        if user.role.name == 'admin'  
         can :manage, :all  
        else  
         can :create , Product  
         can :create , Sale  
         can :read, :all  
        end  
       else  
        can :read, :all  
       end  
      end  
     end  
    
  5.  Edit products_controller tambahkan  load and authorize seperti berikut 
  6.  class ProductsController < ApplicationController  
      before_action :set_product, only: [:show, :edit, :update, :destroy]  
      load_and_authorize_resource  
      # GET /products  
      # GET /products.json  
      def index  
       @products = Product.all  
      end  
      # GET /products/1  
      # GET /products/1.json  
      def show  
      end  
      # GET /products/new  
      def new  
       @product = Product.new  
      end  
      # GET /products/1/edit  
      def edit  
      end  
      # POST /products  
      # POST /products.json  
      def create  
       @product = Product.new(product_params)  
       @product.user_id = current_user.id #tambahkan code ini setelah code diatas   
       respond_to do |format|  
        if @product.save  
         format.html { redirect_to @product, notice: 'Product was successfully created.' }  
         format.json { render :show, status: :created, location: @product }  
        else  
         format.html { render :new }  
         format.json { render json: @product.errors, status: :unprocessable_entity }  
        end  
       end  
      end  
      # PATCH/PUT /products/1  
      # PATCH/PUT /products/1.json  
      def update  
       respond_to do |format|  
        if @product.update(product_params)  
         format.html { redirect_to @product, notice: 'Product was successfully updated.' }  
         format.json { render :show, status: :ok, location: @product }  
        else  
         format.html { render :edit }  
         format.json { render json: @product.errors, status: :unprocessable_entity }  
        end  
       end  
      end  
      # DELETE /products/1  
      # DELETE /products/1.json  
      def destroy  
       @product.destroy  
       respond_to do |format|  
        format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }  
        format.json { head :no_content }  
       end  
      end  
      private  
       # Use callbacks to share common setup or constraints between actions.  
       def set_product  
        @product = Product.find(params[:id])  
       end  
       # Never trust parameters from the scary internet, only allow the white list through.  
       def product_params  
        params.require(:product).permit(:code, :name, :price, :user_id)  
       end  
     end  
    
  7. Edit sales_controller tambahkan  load and authorize seperti berikut
  8.  class SalesController < ApplicationController  
      before_action :set_sale, only: [:show, :edit, :update, :destroy]  
      load_and_authorize_resource  
      # GET /sales  
      # GET /sales.json  
      def index  
       @sales = Sale.all  
      end  
      # GET /sales/1  
      # GET /sales/1.json  
      def show  
      end  
      # GET /sales/new  
      def new  
       @sale = Sale.new  
      end  
      # GET /sales/1/edit  
      def edit  
      end  
      # POST /sales  
      # POST /sales.json  
      def create  
       @sale = Sale.new(sale_params)  
       @sale.user_id = current_user.id #tambahkan ini setelah code di atas   
       @sale.total = @sale.total_all #tambahkan ini setelah code di atas  
       respond_to do |format|  
        if @sale.save  
         format.html { redirect_to @sale, notice: 'Sale was successfully created.' }  
         format.json { render :show, status: :created, location: @sale }  
        else  
         format.html { render :new }  
         format.json { render json: @sale.errors, status: :unprocessable_entity }  
        end  
       end  
      end  
      # PATCH/PUT /sales/1  
      # PATCH/PUT /sales/1.json  
      def update  
       respond_to do |format|  
        if @sale.update(sale_params)  
         format.html { redirect_to @sale, notice: 'Sale was successfully updated.' }  
         format.json { render :show, status: :ok, location: @sale }  
        else  
         format.html { render :edit }  
         format.json { render json: @sale.errors, status: :unprocessable_entity }  
        end  
       end  
      end  
      # DELETE /sales/1  
      # DELETE /sales/1.json  
      def destroy  
       @sale.destroy  
       respond_to do |format|  
        format.html { redirect_to sales_url, notice: 'Sale was successfully destroyed.' }  
        format.json { head :no_content }  
       end  
      end  
      private  
       # Use callbacks to share common setup or constraints between actions.  
       def set_sale  
        @sale = Sale.find(params[:id])  
       end  
       # Never trust parameters from the scary internet, only allow the white list through.  
       def sale_params  
        params.require(:sale).permit(:name, items_attributes: [:id,:product_id, :price,:quantity,:total,:_destroy])  
       end  
     end  
    
  9. Edit aplication_controller tambahkan baris code berikut
  10.   rescue_from CanCan::AccessDenied do |exception|  
       flash[:error] = "Access denied."  
       redirect_to root_url  
      end  
    
  11. Untuk link tinggal di kasih kondisi seperti berikut
  12.      <td><%= link_to 'Show', sale %></td>  
         <% if can? :update, Sale %>  
          <td><%= link_to 'Edit', edit_sale_path(sale) %></td>  
         <%end%>  
         <% if can? :destroy, Sale %>  
          <td><%= link_to 'Destroy', sale, method: :delete, data: { confirm: 'Are you sure?' } %></td>  
         <% end %>  
    

Public Activities

Fitur ini bertujuan untuk mencatat aktifitas user pada aplikasi. Sehingga apabila ada karyawan yang melakukan aktifitas pelanggaran / kecurangan, sistem admin bisa melihat bukti aktifitasnya.
  1. Generate public_activity
  2. $ rails g public_activity:migration
    $ rake db:migrate
  3. Di aplication_controller.rb tambahkan code
  4.  include PublicActivity::StoreController  
    
  5. Di model product.rb dan sale.rb  tambahkan code berikut
  6.  include PublicActivity::Model  
      tracked owner: ->(controller, model) { controller && controller.current_user}  
    
  7. Buat controller untuk  activities
  8. $ rails g controller activities 
  9. Di routesnya tambahkan code
  10.   root to: 'home#index'  
      resources :activities  
    
  11. Di controllernya tambahkan code berikut 
  12.  class ActivitiesController < ApplicationController  
      def index  
       @activities = PublicActivity::Activity.order("created_at desc")  
      end  
     end  
    
  13. Di viewnya buat file index.html.erb di folder activities isi dengan code berikut
  14.  <h1>Listing Activities</h1>  
     <table class="table table-striped table-bordered table-condensed sortable">  
       <thead>  
         <tr>  
           <th><%= "Activities"%></th>  
         </tr>  
       </thead>  
       <tbody>  
            <% @activities.each do |activity| %>  
         <tr>  
           <td valign="top">   
             <%= activity.owner.email %>  
             <%= render_activity activity %>  
           </td>  
         </tr>  
         <% end %>  
       </tbody>  
       <tfoot>  
         <tr>  
           <td colspan="3"></td>  
         </tr>  
       </tfoot>  
     </table>  
    
  15. Buat folder public_activity di view
  16. Di dalam folder public_activity buat folder product dan sale
  17. Di dalam folder product dan sale buat file html partial _create.html.erb ,_update.html.erb, _destroy.html.erb
  18. Create.html.erb  codenya seperti berikut
  19.  added product  
     <% if activity.trackable %>  
      <%= link_to activity.trackable.name, product_path(activity.trackable.id) %>  
     <% else %>  
      which has since been removed  
     <% end %>  
    
  20. _update.html.erb
  21.  Updated product  
     <% if activity.trackable %>  
      <%= link_to activity.trackable.name, product_path(activity.trackable.id) %>  
     <% else %>  
      which has since been removed  
     <% end %>  
    
  22. _destroy.html.erb
  23.  removed a produc  
    
  24. Masuk folder layout dan edit file application.html.erb tambahkan code dibawah class nav navbar-nav
  25.  ·<li><%= link_to "All Activities", activities_path %></li>  
    
  26. Terakhir lakukan proses insert, update dan delete di http://localhost:3000/sales dan http://localhost:3000/products
  27. Hasilnya  bisa di akses di http://localhost:3000/activities

Membuat Aplikasi POS dengan Ruby on Rails 4 part 1

Pengelolaan keuangan adalah salah satu hal pokok yang harus diperhatikan oleh usaha kecil dan menengah (UKM). Untuk membantu memantau kondisi bisnis, kita membutuhkan software Point of Sales ( POS) sederhana yang dapat membantu mencatat aktivitas transaksi. Berikut beberapa fitur yang akan di bangun :
  1. Management Barang
  2. Management Penjualan
  3. Management User + Login

Persiapan

Pastikan di komputermu sudah terinstall:

  1. Ruby versi 2.x
  2. Rails versi 4.x
  3. Database Mysql 
  4. Mozila Firefox   
Kemudian berikut adalah Gems yang akan kita gunakan:
  1. Devise
  2. Cancan
  3. Nested Form
  4. Public Activity

Buat Project Baru 

  1. Membuat project baru dengan mysql
  2. $ rails new sales -d mysql 
    $ cd sales
  3. Edit gemfile tambahkan code baris berikut
  4.   gem 'devise'   
      gem "cancancan"   
      gem "nested_form"    
      gem 'public_activity'  
    
    $ bundle install

Memasang Bootstraps

  1. Buka url http://getbootstrap.com/getting-started/#download
  2. Setelah download copy dan paste isinya ke dalam folder sales/app/assets
  3. Semua file di folder  css copy dan paste  di sale/app/stylesheets
  4. Semua file di folder js copy dan paste di sale/app/javascripts

Home

  1. kita buat controller dan foldernya view lewat comand
  2. rails g controller home 
  3. Buat file index di view/home
  4. Isi dengan <p>welcome</p>
  5. Edit config/routes.rb tambahkan kode berikut
  6.  root to: 'home#index'  
    

Memasang Devise

OK sampai sini bootstrap dan homenya sudah dibuat, sekarang kita akan buat login untuk user, berikut langkahnya
  1. Generate devise 
  2. $ rake db:create
    $ rails generate devise:install
    $ rails generate devise User
    $ rails generate model role name:string
    $ rails g migration addRoleIdToUser role_id:integer
  3. Setelah selesai lakukan migration database
  4. $ rake db:migrate
  5. Masuk ke folder app -> models kemudian Edit file model user dan role.rb
     class User < ActiveRecord::Base  
        belongs_to :role
        devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :trackable, :validatable
    end
    
  6.   
     class Role < ActiveRecord::Base  
        has_many :users  
     end  
    
  7. Edit seed.rb di folder db
  8.  r1 = Role.create(:name => 'user')  
     r2 = Role.create(:name => 'admin')  
     us1 = User.create(:email => 'user@gmail.com' , :password => 'q1w2e3r4', :role_id => r1.id)   
     us2 = User.create(:email => 'admin@gmail.com' , :password => 'q1w2e3r4', :role_id => r2.id)  
    
  9. Untuk memasukan data jalankan perintah berikut
    $ rake db:seed
  10. Untuk membuat user yang sign_up defautlnya adalah role user tambahkan code berikut di model user.rb
  11.   before_create :set_default_role  
      private  
      def set_default_role  
       self.role ||= Role.find_by_name('user')  
      end  
    
  12. Untuk menjalankan server ketikan code berikut di terminal 
  13. $ rails s
  14. Buka browser ketikan http://localhost:3000/users/sign_in maka akan tampil halaman seperti berikut 

Layout

Kita akan membuat desain utama aplikasi ini ,cukup mudah karena desainnya sangat sederhana
  1. Edit file application.html.erb
  2.   <!DOCTYPE html>   
      <html>   
      <head>   
        <title>Sale</title>   
        <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>   
        <%= javascript_include_tag "application", "data-turbolinks-track" => true %>   
        <%= csrf_meta_tags %>   
      </head>   
      <body>   
        <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">   
           <div class="container">   
             <div class="navbar-header">   
                <a class="navbar-brand" href="#">Sale</a>   
             </div>   
             <ul class="nav navbar-nav">    
             </ul>   
             <ul class="nav navbar-nav navbar-right">   
                <% if user_signed_in? %>   
                <li><%= link_to current_user.email, edit_user_registration_path %></li>   
                <li><%= link_to "Log Out" , destroy_user_session_path, method: :delete %></li>   
                <% else %>   
                <li><%= link_to "Sign In", user_session_path %></li>   
                <li><%= link_to "Register", new_user_registration_path %></li>   
                <% end %>   
             </ul>   
           </div>   
        </div>   
        <div class="container">   
           <% flash.each do |type, message| %>   
           <div class="alert <%= flash_class type %> alert-dismissable">   
             <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>   
             <p><%= message %></p>   
           </div>   
           <% end %>   
           <%= yield %>   
        </div>   
      </body>   
      </html>   
    
  3. Edit application_helper.rb
  4.  def flash_class(type)  
      case type  
      when :alert  
        "alert-danger"  
      when :notice  
        "alert-success"  
       else  
        "" end  
     end  
    
  5. Edit file aplication.css di folder app/assets/stylesheet
  6.  body {  
           padding-top: 70px;  
     }  
    
  7. Layoutnya nanti akan seperti gambar berikut

Generate Model dan Controller

Kita akan generate model dan controller, tujuannya agar tidak buat file satu persatu  
  1. Scaffold untuk generate view model dan controller  
  2. $ rails g scaffold product code:string name:string price:decimal user:belongs_to
    $ rails g scaffold sale name:string total:decimal user:belongs_to
  3. Model untuk generate model saja
  4. $ rails g model item product:belongs_to sale:belongs_to quantity:decimal total:decimal
  5.  Setelah selesai databasenya di migrate atau di reset ulang 
  6. $ rake db:migrate
  7. Masuk folder model pada file product tambahkan code berikut
  8.  has_many :items  
    
  9. Masuk folder model pada file sale tambahkan code berikut
  10.  has_many :items  
    
  11. Edit form partial _form.html.erb di folder view/products dan view/sales hapus baris code berikut
  12.   <div class="field">  
       <%= f.label :user_id %><br>  
       <%= f.text_field :user_id %>  
      </div>  
    
  13. Edit file index.html.erb di folder view/products hapus baris code berikut
  14.  <th>User</th>  
    
     <td><%= product.user %></td>  
    
  15. Edit file index.html.erb di folder view/sales hapus baris code berikut
  16.  <th>User</th>  
    
     <td><%= sale.user %></td>  
    
  17. Untuk memasang tema bootstrap ke dalam tabel edit index.html.erb di folder products and sales perhatikan baris <table> dan tambahkan code berikut
  18.  <table class="table table-striped">  
    
  19. Edit aplication.html.erb di folder layout tambahkan baris code setelah tag <ul class="nav navbar-nav"> </ul>
  20.  <li><%= link_to "All Sales", sales_path %></li>  
     <li><%= link_to "All Products", products_path %></li>  
    
  21. View tablenya akan seperti berikut


Untuk selanjutnya silahkan cek link ini: Membuat Aplikasi POS dengan Ruby on Rails 4 Part 2

Selasa, 18 Maret 2014

ActionMailer ( Part 2 )

Pada pertemuan sebelumnya, kita telah membahas topik tentang Action Mailer Basic pada Ruby on Rails. Kali ini kita akan membahas tentang kasus yang lebih advance yang masih berhubungan dengan ActionMailer.

Sebagai contoh disini adalah email akan dikirimkan ke semua user apabila seorang user telah memposting iklan baru.

Pertama, buat model user terlebih dahulu menggunakan devise. Untuk install gem devise, cukup tambahkan
gem 'devise'
pada Gemfile lalu jalankan bundle install di console. Setelah itu jalankan
rails generate devise:install
Baru kita buat model usernya yang telah digenerate dengan devise
rails generate devise user
Lalu jalankan rake db:migrate pada console

Setelah itu kita buat resource untuk post. Agar lebih mudah kita gunakan scaffold. Karena scaffold memudahkan kita untuk menggenerate model, view dan controllers sekaligus.
rails generate scaffold posts
Lalu kita isi tabel post tersebut dengan beberapa kolom, misalkan
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.integer :price
      t.text :description
      t.integer :user_id
      t.timestamps
    end
  end
end
Buat relasi antara user dan post. Post dimiliki oleh user dan user bisa memiliki banyak posts.
class User < ActiveRecord::Base
  has_many :posts, :dependent => :destroy
end
class Post < ActiveRecord::Base
  belongs_to :user
end
Lalu kita buat method untuk mengirim email ke semua user kecuali user yang memposting iklan tersebut. Email baru akan dikirm setelah user membuat posting iklannya.
Pada file apps/controllers/posts_controllers.rb, include method untuk mengirimkan email setelah post tersebut berhasil disimpan. Misalkan method tersebut diberi nama users_notification. Dalam method tersebut terdapat parameter untuk post dan list user yang akan dikirimkan emailnya. 
class PostsController < ApplicationController
...
def create
    @post = Post.new(params[:post])
    @post.user_id = current_user.id
    respond_to do |format|
      if @post.save
        @users = User.except_this_user(@post)
        unless @users.blank?
          @users.each do |user|
            PostMailer.users_notification(@post, user).deliver
          end
        end
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render json: @post, status: :created, location: @post }
      else
        format.html { render action: "new" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end
...
end

Untuk list user, kita buat methodnya juga pada model user.rb. List user tersebut adalah semua user kecuali user yang memposting iklan tersebut. 
class User < ActiveRecord::Base
...
  def self.except_this_user(post)
    User.find(:all, :conditions => ["id != ?", post.user_id])
  end
...
end
Setelah itu kita buat method pada post mailernya
class PostMailer < ActionMailer::Base
  default from: "username@email.com"

  def self.users_notification(post, user)
   @post = post
   @user = user
   mail(:to => @user.email, :subject => "Notifikasi iklan baru")
  end

end
Terakhir, kita buat view untuk mailernya. Kita buat view dengan sesuai dengan nama method di mailernya users_notification.html.erb. 
<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
  </head>
  <body>
    <p>Hi <%= @user.email%>,<br/>
     <%= @post.user.email %> telah memposting iklan baru :<br/>
     Judul : <%= @post.title %><br/>
     Harga : <%= @post.price %><br/>
     Deskripsi : <%= raw @post.description %><br/>
    </p>
    Terima kasih
  </body>
</html>
Setelah semua selesai kita bisa mencoba ActionMailer tersebut dengan mengentry postingan terbaru.



Email akan terkirim ke semua user secara otomatis setelah post tersebut dibuat.


Selamat mencoba dan happy coding :-)





Selasa, 25 Februari 2014

ActionMailer ( Part 1 )

ActionMailer memungkinkan Anda untuk mengirim email dari web aplikasi yang Anda buat dengan menggunakan class mailer dan view. Sebagai contoh di sini adalah mengirim email pada halaman list user di Admin.

Berikut ini akan dijelaskan cara setting ActionMailer pada aplikasi Rails :

1. Pastikan sudah ada account email yang akan digunakan untuk mengirim email secara default. Biasanya account email yang digunakan adalah account gmail. Pastikan account gmail tersebut IMAP nya sudah di-enable supaya bisa mengirim email dari aplikasi kita. Pada account gmail Anda, pilih Setting lalu pilih tab Forwarding and POP/IMAP lalu pilih radio button Enable IMAP.



2. Setelah account Gmail tersebut disetting, lalu kita setting mailer SMTP pada aplikasi kita. Ubah file config/environment/development.rb atau config/environment/production.rb  dan ubah sesuai account gmail yang akan diset sebagai pengirim seperti email dan password nya.
#Gmail SMTP
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address              => "smtp.gmail.com",
    :port                 => 587,
    :domain               => 'localhost:3000',
    :user_name            => 'username@email.com',
    :password             => 'yourpassword',
    :authentication       => 'plain',
    :enable_starttls_auto => true  }
Setelah langkah di atas sudah diikuti, lalu kita buat mailernya misalkan user_mailer. Ketikkan pada console 
rails g mailer UserMailer
Seperti yang Anda lihat, Anda dapat menghasilkan mailer seperti Anda menggunakan generator lain dengan Rails. Mailer secara konseptual mirip dengan controller, sehingga kita mendapatkan mailer, sebuah direktori untuk view dan test.

Setelah itu edit mailer yang baru dibuat tersebut dengan set default email dengan alamat email yang sudah ditentukan
class UserMailer < ActionMailer::Base
  default from: "from@example.com"
end
Sebagai contoh, kita buat method welcome_email yang maksudnya mengirim email kepada user yang baru dibuat.
class UserMailer < ActionMailer::Base
  default from: "from@example.com"

  def welcome_email(user)
   @user = user
   @url = "http://localhost:3000"
   mail(:to => @user.email, :subject => "Welcome to my awesome site")
  end
end
Lalu pada model user, buat callback after_create seperti ini 
class User < ActiveRecord::Base
  after_create :send_welcome_email

  def send_welcome_email(user)
    UserMailer.welcome_email(self).deliver
  end
end
Lalu kita buat viewnya 
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Welcome to example.com, <%= @user.name %></h1>
    <p>
      You have successfully signed up to example.com,
      your username is: <%= @user.login %>.<br/>
    </p>
    <p>
      To login to the site, just follow this link: <%= @url %>.
    </p>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html>
Setelah itu, baru kita bisa mencoba membuat user dan email akan terkirim secara otomatis ke user yang baru dibuat.

Sumber lengkap : http://guides.rubyonrails.org/action_mailer_basics.html

Selamat mencoba dan happy coding :)

Selasa, 18 Februari 2014

Installasi CKeditor pada aplikasi Ruby on Rails

CKEditor adalah editor teks HTML yang siap untuk digunakan dan dirancang untuk menyederhanakan pembuatan konten web. Dari mulai menyisipkan link, mengubah warna text, mengubah font, menambahkan bullet and numbering dan masih banyak fitur lainnya. Misalnya Anda ingin membuat sebuah konten dalam web yang menampilkan paragraf bergambar. Dengan Ckeditor akan lebih mudah dalam pembuatannya, proses pembuatannya mirip sekali dengan editor di Microsoft Word atau word editor yang lain. Namun tentunya dengan CKeditor pembuatannya akan lebih sederhana.

Berikut ini akan dijelaskan installasi CKeditor pada aplikasi Ruby on Rails :

  1. Tambahkan gem ckeditor pada Gemfile, lalu jalankan bundle install
gem 'ckeditor'
    2.  Untuk generate model file upload biasanya menggunakan gem paperclip. Tambahkan terlebih dahulu gem paperclip di Gemfile lalu jalankan ini di console
gem 'paperclip'
rails generate ckeditor:install --orm=active_record --backend=paperclip
   3. Misalkan aplikasi yang kita buat adalah membuat blog. Agar lebih mudah gunakan scaffold untuk menggenerate controller dan modelnya.
rails generate scaffold blogs
4.  Setelah digenerate di console, untuk model blog tambahkan 2 kolom misalkan kolom untuk 'title' dan 'body'. Lalu jalankan perintah rake db:migrate
class CreateBlogs < ActiveRecord::Migration
  def change
    create_table :blogs do |t|
      t.string :title
      t.text :body
      t.timestamps
    end
  end
end

5.  Setelah itu include ckeditor javascript pada file application.js
//= require ckeditor/init
Bila aplikasi yang dibuat menggunakan rails 4, maka include ini terlebih dahulu sebelum ckeditor/init pada file application.js
//= require ckeditor/override
//= require ckeditor/init
catatan: apabila membuatnya di OS Windows terjadi error, hapus baris ini :
//= require ckeditor/override

6.  Baru setelah itu kita bisa menyisipkan ckeditor pada form yang akan dibuat. Misalkan kita akan membuat halaman create new blog. Pada bagian body, cukup tambahkan cktext_area untuk memuat ckeditornya.
<%= f.label :title %>:<span><%= f.text_field :title %></span>
 <br/>
<%= f.label :body %>:
 <br/>
<%= f.cktext_area :body, :width => 100 %>
<%= f.submit %>
Hasilnya kurang lebih akan terlihat seperti ini


Selamat mencoba dan happy coding :)