Fungsi Generate Code
Product mempunyai attribut code dan codenya nanti akan di generate secara otomatis.Attribut ini nantinya bisa digunakan untuk barcode.
- Pada folder view/productIndex dan formnya dirubah
- File _form.html.erb bagian user dan codenya di hilangkan
- Untuk index.html.erb codenya seperti berikut
- Tambahkan code pada model product
- Selanjutnya di controller productnya tambahkan baris berikut pada method create
- Lakukan input data di url http://localhost:3000/products/new
<%= 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 %>
<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 %>
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
@product = Product.new(product_params)
@product.user_id = current_user.id #tambahkan code ini setelah code diatas
Membuat Nested Form
- Edit model sale.rb tambahkan code berikut
- Edit partial _form.html.erb di dalam folder view/sales
- Edit aplication_helper.rb tambahkan code berikut
- buat file partial _item_fields.html.erb di folder sales/app/views/sales/ isinya seperti berikut
- Periksa di http://localhost:3000/sales/new hasilnya akan seperti gambar berikut
has_many :items
accepts_nested_attributes_for :items, allow_destroy: true
<%= 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>
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
<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>
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:- Edit model item ketikan code berikut:
- Edit model sale untuk menghitung total harga penjualan berikut codenya
- Edit controllers sales_controller.rb
- Tambahkan pada method create code berikut
- Tambahkan parameter yang akan di permit
- Lakukan input data penjualan http://localhost:3000/sales/new tambahkan beberapa item kemudian simpan
- Periksa apakah total penjualanya terhitung
- Edit file show di folder view sale
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
def subtotals
self.items.map { |i| i.subtotal }
end
def total_all
subtotals.sum
end
@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
params.require(:sale).permit(:name, items_attributes: [:id,:product_id, :price,:quantity,:total,:_destroy])
<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.- Generate cancan
- Tambahkan code di class ability.rb seperti berikut:
- Edit products_controller tambahkan load and authorize seperti berikut
- Edit sales_controller tambahkan load and authorize seperti berikut
- Edit aplication_controller tambahkan baris code berikut
- Untuk link tinggal di kasih kondisi seperti berikut
$ rails g cancan:ability
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
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
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
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = "Access denied."
redirect_to root_url
end
<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.- Generate public_activity
- Di aplication_controller.rb tambahkan code
- Di model product.rb dan sale.rb tambahkan code berikut
- Buat controller untuk activities
- Di routesnya tambahkan code
- Di controllernya tambahkan code berikut
- Di viewnya buat file index.html.erb di folder activities isi dengan code berikut
- Buat folder public_activity di view
- Di dalam folder public_activity buat folder product dan sale
- Di dalam folder product dan sale buat file html partial _create.html.erb ,_update.html.erb, _destroy.html.erb
- Create.html.erb codenya seperti berikut
- _update.html.erb
- _destroy.html.erb
- Masuk folder layout dan edit file application.html.erb tambahkan code dibawah class nav navbar-nav
- Terakhir lakukan proses insert, update dan delete di http://localhost:3000/sales dan http://localhost:3000/products
- Hasilnya bisa di akses di http://localhost:3000/activities
$ rails g public_activity:migration
$ rake db:migrate
include PublicActivity::StoreController
include PublicActivity::Model
tracked owner: ->(controller, model) { controller && controller.current_user}
$ rails g controller activities
root to: 'home#index'
resources :activities
class ActivitiesController < ApplicationController
def index
@activities = PublicActivity::Activity.order("created_at desc")
end
end
<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>
added product
<% if activity.trackable %>
<%= link_to activity.trackable.name, product_path(activity.trackable.id) %>
<% else %>
which has since been removed
<% end %>
Updated product
<% if activity.trackable %>
<%= link_to activity.trackable.name, product_path(activity.trackable.id) %>
<% else %>
which has since been removed
<% end %>
removed a produc
·<li><%= link_to "All Activities", activities_path %></li>
makasih pak tutorial nya
BalasHapussaya ada masalah di baris
<%= f.fields_for :items do |builder| %>
keterangan
uninitialized constant Sale::Item
tolong dibantu ya pak ? makasih :)
BalasHapusItu karena Model itemnya belum ada.
Ada yang terlewat, yaitu: baris perintah
rails g model item product:belongs_to sale:belongs_to quantity:decimal total:decimal
coba periksa kembali part 1
Thanks,
ini postingan paling menakjubkan pak, thank's a lot brother . . :)
BalasHapusditunggu postingan selanjutnya pak . .
Siap, makasih bro
HapusSangat bermanfaat
BalasHapusMakasih :)
HapusVery nice Post, sebagai tambahan, edit activities_controller.rb:
BalasHapusclass ActivitiesController < ApplicationController
def index
@activities = PublicActivity::Activity.all
end
end
Makasih Mas,
HapusIya ada yang kurang, makasih sudah diingatkan :D
Kita tambahkan sekarang
Salam,
BalasHapusTrimkasih sdh berbagi postingan yg sgt bermanfaat bagi kami pembaca.
Saya punya saran, bagaimana dibuat postingan review aplikasi yg pernah ada atau yg opensource basia ruby on rails (misalnya aplikasi pos, crm, cms, edms, dll)
Tks
Salam,
HapusThanks masukannya Mas Yudha.
Ide bagus, akan kami coba buat untuk post mendatang.
useful banget mas
BalasHapusmakasih Mas
HapusKerenn infonyaa
BalasHapussedikit saran di tutorial nya saat membuat public_activity :
BalasHapustutorial no 8 membuat folder public_activity terdapat tutorial no 9
jadi :
public_activity
----->activity
---->product
---->sale
terima kasih
Ok thanks masukan nya Mas
Hapusom saya ada masalah di error ini knp ya??
BalasHapusActionView::MissingTemplate in Sales#new
Error itu artinya kamu load view yang tidak ada.
Hapussaya ada masalah penambahan file patial item, nah file itu di taruh dmna ya???
BalasHapusdi folder sales/app/views/sales/
HapusMas mau tanya di Fungsi Hitung Penjualan bagian menambah bagian user id di sale "@sale.user_id = current_user.id" kok saya error begini ya? NoMethodError in SalesController#create
BalasHapusundefined method `id' for nil:NilClass .. Mohon infonya, trims
User login nya udah di implementasi belum Mas ?
Hapusada yg kurang gan untuk destroy nya, saya error
BalasHapusError: Cannot delete or update a parent row: a foreign key constraint fails (`sales_development`.`items`, CONSTRAINT `fk_rails_f6e50c029b` FOREIGN KEY (`sale_id`) REFERENCES `sales` (`id`)): DELETE FROM `sales` WHERE `sales`.`id` = 5
Mas Keci, error ini karena kamu mau delete data sales yang sudah ada items nya ( child data )
HapusKomentar ini telah dihapus oleh administrator blog.
BalasHapusmantap pak, lumayan buat refrensi rails di indonesia. mantap pak, ditunggu blog selanjutnya
BalasHapus