lab2023.com
lab2023 official blog
http://lab2023.com/
2019-03-19T03:00:00+03:00
Rails Girls Denizli 2019 Etkinliği Nasıl Geçti?
http://lab2023.com/rails-girls-denizli-2019-etkinligi-nasil-gecti.html
2019-03-19T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Rails Girls, kadınların Ruby on Rails teknolojisini anlamalarını ve bu teknolojiyi kullanarak fikirlerini inşa etmelerini
sağlamaya teşvik etmek amacıyla kurulmuş olan, Finlandiya kökenli bir topluluktur. </p>
<p>15 - 16 Mart 2019 tarihinde Lab2023 firması organizatörlüğünde Denizli'de 3.sünü düzenlemiş olduğumuz etkinlikte
katılımcılarımız ve koçlarımızla birlikte eğlenceli ve bilgilendirici iki gün geçirdik.</p>
<p><a href="http://railsgirls.com/denizli2019"><img alt="railsgirlsdenizli" src="assets/images/articles/2019-03-19-rails-girls-denizli-2019-etkinligi-nasil-gecti/gun-1.jpg" /></a></p>
<h3 id="rails-girls-1-g-n-kurulum-partisi">Rails Girls 1.Gün: Kurulum Partisi</h3>
<p>Etkinliğimizin ilk gününü, katılımcılarımızla tanışma ve bilgisayarlarına gerekli kurulumların yapılması ile geçirdik.
Uygulama geliştirirken kullanacak olduğumuz Linux komutları ve Git kavramını anlatmaya çalıştık.</p>
<p><a href="http://railsgirls.com/denizli2019"><img alt="railsgirlsdenizli" src="assets/images/articles/2019-03-19-rails-girls-denizli-2019-etkinligi-nasil-gecti/gun-2.jpg" /></a></p>
<h3 id="rails-girls-2-g-n">Rails Girls 2.Gün</h3>
<p>Etkinliğimizin ikinci gününde, ‘Ruby’ ve ‘Ruby on Rails’ teknolojileri hakkında bilgi verdik. Hemen ardından gerçek bir
uygulama geliştirme sürecine başladık.
Kadınlarımızın iş hayatında daha fazla bulunmasını sağlamak amacıyla, onlara iş kurma süreçlerinde nasıl bir yol
izlemeleri gerektiğine dair Yeliz Koç Erikan tarafından ‘Tim/Teb Girişim Evi’ sunumuyla bilgi verdik. Ayrıca, örnek
olması için çağırdığımız, Dr. Öğretim Üyesi Arzum Işıtan'ın ‘Girişimci Kadın Mühendis’ konuşması katılımcılarımıza ilham kaynağı oldu.
Daha sonra, Web uygulamalarında kullandığımız teknolojileri keyifli bir şekilde anlamalarını sağlayacak Bentobox
çalışmasını gerçekleştirdik.
Sunumlar ve Bentobox çalışmalarımız ardından, web uygulaması çalışmamıza kaldığımız yerden devam ettik.</p>
<p><a href="http://railsgirls.com/denizli2019"><img alt="railsgirlsdenizli" src="assets/images/articles/2019-03-19-rails-girls-denizli-2019-etkinligi-nasil-gecti/all.jpg" /></a></p>
Rails Girls Denizli Etkinliği
http://lab2023.com/rails-girls-denizli-etkinligi.html
2019-01-07T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p><a href="http://railsgirls.com/">Rails Girls</a> Finlandiya’da kurulmuş bir topluluktur. Amacı Rails kodlayan kadın sayısını artırmaktır.
Rails Girls topluluğu birçok ülkede başarılı projelere imza atmaktadır. Rails Girls etkinliği <a href="http://lab2023.com/">Lab2023</a>’ün organizatörlüğünde Denizli ’de üçüncü kez düzenleniyor.
3. Rails Girls Denizli etkinliği 1 - 2 Mart tarihleri arasında Pamukkale Teknokent Konferans salonunda gerçekleşecek.
Etkinliğe katılım ve bilgi almak için <a href="http://railsgirls.com/denizli2019">railsgirls.com/denizli2019</a> adresini ziyaret edebilirsiniz.
Daha önce Denizli'de düzenlenen Rails Girls etkinliği ile ilgili resimlerin tamamını <a href="https://www.flickr.com/photos/122188945@N05/sets/72157644393068979/">Flickr hesabımızdan</a> görebilirsiniz.</p>
<p>Rails, Ruby programlama diliyle yazılmış, açık kaynak kodlu bir web uygulama geliştirme çerçevesidir.
Sade ve kısa bir sözdizimi sayesinde kullanıcı sayısı her geçen gün artmaktadır. Bu etkinliğin amacı her
yaştan kadının Rails’i tanıması, web dünyasını öğrenmesi ve küçük web uygulamaları yapabilmeleridir.
Bu uygulamalar sayesinde kadınlar kod yazmanın zor olmadığını farketmeye başlayacak ve ön yargılarından
kurtulacaklardır. Etkinliğe yanlarında bir kadının eşlik etmesi halinde konuyla ilgilenen erkekler de katılabiliyor.</p>
<p>Rails Girls etkinliğini en güzel yanlarından birisi de Rails konusunda uzman kişilerin etkinlik sırasında
size mentorluk etmesi ve yönlendirmesi. Etkinliğe katılmak için programcılık bilgisine sahip olmanıza gerek yoktur.</p>
<p><a href="http://lab2023.com/">Lab2023</a> organizatörlüğünde 1 - 2 Mart 2019 tarihleri arasında Denizli’de <a href="http://pauteknokent.com.tr/teknokent/">Pamukkale Teknokent</a>,
<a href="http://www.denizlihs.org/">Denizli Hackerspace</a> ve <a href="http://lab2023.com/">Lab2023</a> ‘ün sponsorluk destekleriyle gerçekleşecek olan Rails Girls etkinliğinin programı şu şekildedir.</p>
<ul>
<li><p>Cuma akşamı katılımcılar ve mentörler ile tanışma ve kurulum partisi yapılacaktır. Bu partide cumartesi günü neler yapılacağı
anlatılacak ve katılımcıların bilgisayarlarına gerekli programların kurulması sağlanacaktır.</p></li>
<li><p>Cumartesi günü ise eğitime başlanacak ve küçük uygulamalar yapılarak bir proje ortaya çıkarılacak.</p></li>
</ul>
<p>Bu güzel etkinliğe son katılım tarihi, 21 Şubat 'tır.</p>
<p>Katılmak için <a href="http://railsgirls.com/denizli2019">railsgirls.com/denizli2019</a> adresindeki formu doldurmanız yeterli.</p>
<hr>
<p><a href="http://railsgirls.com/denizli2019"><img alt="railsgirlsdenizli" src="assets/images/articles/2019-01-07-rails-girls-denizli-etkinligi/railsgirlsdenizli2019.png" /></a></p>
Web Geliştiricisi İş İlanı
http://lab2023.com/web-gelistiricisi-is-ilani.html
2018-02-08T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p><img alt="web-developer-job-application-cover" src="assets/images/articles/2018-02-08-web-gelistiricisi-is-ilani/web-developer-job-application-cover.jpg" /></p>
<h2 id="tan-m">İş Tanımı</h2>
<p>Ekibimize katılmak üzere en az 2 yıl deneyimli tam zamanlı web geliştiricileri arıyoruz. Geliştiricilerden sadece ürün geliştirmelerini değil blog yazısı, webinar, etkinliklere konuşmacı olarak katılması ve açık kaynak projelere katkıda bulunmasını bekliyoruz.</p>
<h2 id="teknik-nitelikler">Teknik Nitelikler</h2>
<ul>
<li>HTML, CSS, JavaScript vb. web teknolojilerine hakim olmak.</li>
<li>Ruby, Python, PHP, Java gibi web geliştirmede kullanılabilen en az bir dile hakim olmak. </li>
<li>Rails, Django, Laravel yada Spring gibi en az bir geliştirme çatısına hakim olmak.</li>
<li>OOP, MVC, ORM, SOLID, Tasarım şablonları, TDD & BDD, Debug, Refactoring kavramlarını bilmek.</li>
<li>Agile, Scrum kültürünü bilmek.</li>
</ul>
<h2 id="tercih-nedenleri">Tercih Nedenleri</h2>
<ul>
<li>Kullanmakta olduğumuz Ruby, Rails, HAML, SASS, CoffeeScript vb. teknolojileri biliyor olmak. </li>
<li>Uzman olunmasa bile UX, UI, prototipleme konularında fikir sahibi olmak. Kötü yada kullanışsız bir ürün görünce rahatsız olmak. </li>
<li>Ekip üyelerimizin belirli alanlarda uzmanlaşırken yeni teknolojiler öğrenmeye kapalı olmamasını bekliyoruz.</li>
<li>React, React Native, Ember, Bootstrap, Swift, Android, Node.js, Sencha Ext JS, Cordova teknolojilerinden bazılarına
veya benzer popüler teknolojilere ilgi duyuyor veya biliyor olmanız bir avantaj olarak değerlendirilecektir.</li>
<li>Atlassian ürünlerine hakim olmak.</li>
</ul>
<h2 id="genel-nitelikler">Genel Nitelikler</h2>
<ul>
<li>Erkek adaylar için askerlikle ilişkisi olmamak veya en az 2 yıl tecilli olmak.</li>
<li>Yabancı müşteriler ve çalışma arkadaşlarımızla konuşacak seviyede ingilizce bilmek.</li>
</ul>
<h2 id="sunulan-mkanlar">Sunulan İmkanlar</h2>
<ul>
<li>Seviyenize uygun olarak belirlenmiş maaşlarınız, ek mesai ücretiniz, ücretli izinleriniz, vb tüm sosyal haklarınız korunmaktadır.</li>
<li>Yıl içerisinde elde edilen şirketin faaliyet kazancı üzerinden belli bir oranda prim verilmektedir.</li>
<li>Firma olarak 09:00 - 18:00 arasında çalışıyoruz. Mesai bitiminde veya belirlenen çalışma aralığınızdan fazla bir zamanda çalışmanızı istemiyoruz.</li>
<li>Haftada 5 gün (Pazartesi-Cuma) 45 saat çalışıyoruz. Haftanın 4 gününü müşterilerimize 1 gününü ise kendimizi geliştirmeye ayırıyoruz.</li>
<li>Esnek çalışma saatleri ve uzaktan çalışma gibi imkanları çalışanlarımıza sunuyoruz.</li>
<li>iMac, MacBook Pro vb. geliştirme ortamlarında çalışıyoruz.</li>
<li>Ofisimizde atıştırmalıklarımız ve taze kaliteli kahvemiz mevcuttur.</li>
<li>Katılacağınız konferanslara teşvik amaçlı katılım maliyetlerinizi destekliyoruz. Ayrıca konuşmacı olarak katılacağınız etkinlik veya konferanslara ait masraflarınızın tamamını karşılıyoruz.</li>
<li>Sigara kullanmayan adayların fitness salonu ücretlerinin belirli bir kısmı tarafımızdan karşılanmaktadır.</li>
</ul>
<h2 id="ba-vuru-ve-de-erlendirme-s-reci">Başvuru ve Değerlendirme Süreci</h2>
<ul>
<li>Mülakatlar Google Hangout üzerinden 10-15 dakikalık süreler ile yapılır.</li>
<li>Adayın yeteneğine / seviyesine uygun şekilde bir ödev verilecek ve hazırladığı çalışmayı kendi portfolyo sitesi URL, Dribbble, Behance, GitHub, Bitbucket vb. üzerinden bizimle paylaşması istenecektir.</li>
<li>Başka şehirde ikamet eden adaylara uzaktan çalışma imkanı sunulacaktır.</li>
<li>Başka şehirde ikamet ederek uzaktan çalışmak isteyen ve başvurusu kabul edilmiş adaylar, tüm ulaşım, konaklama ve yemek masrafları tarafımızdan karşılanmak üzere Denizli Pamukkale Teknoloji Geliştirme Bölgesinde bulunan ofisimizde en fazla 1 ay süre ile misafir edilecektir. Bu süre zarfında ekip arkadaşlarımız ile birlikte çalışarak ekibimiz ve süreçlerimize adaptasyonu sağlanacaktır.</li>
<li>Süreç ile ilgili <a href="mailto:hello@lab2023.com">hello@lab2023.com</a> adresine email atarak bilgi alabilirsiniz.</li>
</ul>
<h3 id="hemen-ba-vurun"><strong><a href="https://docs.google.com/forms/d/e/1FAIpQLSfFC3Gd_GZmpk5qzhKfx_jpy3g2nb9GkdFTPhmdUEmEc7mgoA/viewform?hl=tr">Hemen Başvurun</a></strong></h3>
<p><img alt="Vrais codeurs" width="650" height="886" src="assets/images/articles/2014-06-20-Vrais-codeurs-650-finalenglish.jpg" /></p>
Hello World - Yazılım ve Tasarım Dünyası İle Tanışın Etkinliği
http://lab2023.com/hello-world-yazilim-ve-tasarim-dunyasi-ile-tanisin-etkinligi.html
2017-05-05T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhaba,</p>
<p>Organizasyonunu üstlendiğimiz,
<a href="http://www.pau.edu.tr">Pamukkale Üniversitesi</a>,
<a href="http://pauteknokent.com.tr">Pamukkale Teknokent</a>,
<a href="https://www.netinternet.com.tr">Netinternet</a>,
<a href="https://www.bulutfon.com">Bulutfon</a> ve
<a href="http://www.denizlihs.org">Denizli Hackerspace</a>’in katkıları ile 11 Mayıs 2017, Perşembe, Saat 14:00'de
Pamukkale Teknokent Konferans Salonu'nda
<strong><q>Hello World - Yazılım ve Tasarım Dünyası İle Tanışın</q></strong> etkinliğini gerçeklestiriyoruz.</p>
<p>Bu etkinliğimize yazılım ve tasarım dünyasına ilgili ve bu alanda kendisini geliştirmek yada çalışmak isteyen
tüm ilgilileri davet ediyoruz.</p>
<p>Detaylar için
<a href="https://www.meetup.com/Denizli-Hackerspace-Meetup-Group/events/239749312/">Denizli Hackerspace Meetup</a>
sayfasını ziyaret edebilirsiniz.</p>
<p>İlgililere duyurulur.</p>
<p><img alt="hello-world-event-poster" src="assets/images/articles/2017-05-05-denizlihs-hello-world-event-poster.jpg" /></p>
<h2 id="etkinlik-eri-i">Etkinlik İçeriği</h2>
<ul>
<li><p>Barış Sevg - Denizli Hackerspoce Nedir? Ne için kuruldu?</p></li>
<li><p>Tayfun Öziş Erikan - Açık Kaynak - Özgür Yazılım Felsefesi, GNU, Linux, Ruby / Ruby on Rails Ekosistemi ve Çevik Yazıım Geliştirme Süreçleri</p></li>
<li><p>Osman Makal - Yeni Nesil Yazılım Altyapı ve Konfigürasyon Yönetimi</p></li>
<li><p>Hamdi Bayhan - Algoritma Nedir? Bazı Algoritma Örnekleri</p></li>
<li><p>Eşref Viduşlu - Github - Bitbucket neden kullanılır?</p></li>
<li><p>Serdar Yağcı - Yapay Zeka 101 / Mühendis olmayanlar için Yapay Zeka</p></li>
<li><p>Salim Gürsoy - Arayüz Tasarımı Nedir? Arayüz Tasarımında Dikkat Edilmesi Gereken Noktalar</p></li>
</ul>
<h2 id="yer-ve-zaman">Yer ve Zaman</h2>
<p>Pamukkale Teknokent Konferans Salonu,
11 Mayıs 2017 Perşembe, 14:00</p>
<p>Görüşmek dileğiyle.</p>
Rails 5'de Fineuploader Kullanımı
http://lab2023.com/rails-5-de-fineuploader-kullanimi.html
2017-03-10T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhabalar,</p>
<p>Bu yazıda sizelere Rails'de Fineuploader kullanımını bazı özelliklerini kullandığımız bir örnek ile göstereceğim.
Fineuploader dosya yükleme işlemleriniz için kullanabileceğiniz bir dosya yükleme kütüphanesidir.
Fineuploader'ı kullanmak için web sayfasına ilk girdiğinizde muadilleri ile arasındaki farkı gösteren tablo ve şu sloganlar:</p>
<ul>
<li>File uploading without the hassle</li>
<li>Everything you need in a JavaScript file upload library</li>
<li>Completely <q>free as in speech</q> open source software, developed by the community, and sponsored by a company that cares.</li>
</ul>
<p>muadilleri yerine Fineuploader'ı kullanmanız için sizi cezbetmeye yetecektir.</p>
<p>Öncelikle <a href="https://fineuploader.com/customize.html"> Fineuploader download </a> sayfasına giderek <code>Traditional</code> için
dosyalarımızı indiriyoruz. Bu dosyamızın içinden <code>jquery.fine-uploader.js</code> dosyamızı <code>vendor/assets/javascripts</code>
klasörünün içine, <code>fine-uploader-gallery.css</code> dosyamızı <code>vendor/assets/stylesheets</code> klasörünün içine atıp
‘javascript’ ve ‘CSS’ dosyalarımıza bağlantılarını yapıyoruz ayrıca şu dosyalarımızı: </p>
<ul>
<li>fine-uploader/loading.gif</li>
<li>fine-uploader/processing.gif</li>
<li>fine-uploader/continue.gif (isteğe bağlı - yükleme durdurma özelliğini kullanacaksanız)</li>
<li>fine-uploader/edit.gif (isteğe bağlı - dosya ismi düzenleme özelliğini kullanacaksanız)</li>
<li>fine-uploader/retry.gif (isteğe bağlı - yüklemesi başarısız olan bir dosyayı tekrar yükleme özelliğini kullanacaksanız)</li>
<li>fine-uploader/trash.gif (isteğe bağlı - dosya silme özelliğini kullanacaksanız).</li>
</ul>
<p><code>assets/images</code> klasörünün içine ve şu dosyalarımızı:</p>
<ul>
<li>fine-uploader/placeholders/not_available-generic.png</li>
<li>fine-uploader/placeholders/waiting-generic.png`</li>
</ul>
<p><code>public/fine_uploader</code>klasörünün içine atıyoruz.</p>
<p>Şu an itibariyle Fineuploader'ın kullanımı için alt yapımızı hazırladık.</p>
<p>Fineuploader'ın arayüz kodlarını için aşağıdaki kodları bir <code>_fine_uploader_template.html.erb</code>` adında partial hale getirelim .</p>
<div class="highlight"><pre class="highlight html"><code><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/template"</span> <span class="na">id=</span><span class="s">"qq-template-gallery"</span><span class="nt">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-uploader-selector qq-uploader qq-gallery</span><span class="dl">"</span> <span class="nx">qq</span><span class="o">-</span><span class="nx">drop</span><span class="o">-</span><span class="nx">area</span><span class="o">-</span><span class="nx">text</span><span class="o">=</span><span class="dl">"</span><span class="s2">Drop files here</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-total-progress-bar-container-selector qq-total-progress-bar-container</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="nx">role</span><span class="o">=</span><span class="dl">"</span><span class="s2">progressbar</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">valuenow</span><span class="o">=</span><span class="dl">"</span><span class="s2">0</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">valuemin</span><span class="o">=</span><span class="dl">"</span><span class="s2">0</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">valuemax</span><span class="o">=</span><span class="dl">"</span><span class="s2">100</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar</span><span class="dl">"</span><span class="o">><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-drop-area-selector qq-upload-drop-area</span><span class="dl">"</span> <span class="nx">qq</span><span class="o">-</span><span class="nx">hide</span><span class="o">-</span><span class="nx">dropzone</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-drop-area-text-selector</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-button-selector qq-upload-button</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span><span class="o">></span><span class="nx">Upload</span> <span class="nx">a</span> <span class="nx">file</span><span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-drop-processing-selector qq-drop-processing</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span><span class="o">></span><span class="nx">Processing</span> <span class="nx">dropped</span> <span class="nx">files</span><span class="p">...</span><span class="o"><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-drop-processing-spinner-selector qq-drop-processing-spinner</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="nx">ul</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-list-selector qq-upload-list</span><span class="dl">"</span> <span class="nx">role</span><span class="o">=</span><span class="dl">"</span><span class="s2">region</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">live</span><span class="o">=</span><span class="dl">"</span><span class="s2">polite</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">relevant</span><span class="o">=</span><span class="dl">"</span><span class="s2">additions removals</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">li</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="nx">role</span><span class="o">=</span><span class="dl">"</span><span class="s2">status</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-status-text-selector qq-upload-status-text</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-progress-bar-container-selector qq-progress-bar-container</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="nx">role</span><span class="o">=</span><span class="dl">"</span><span class="s2">progressbar</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">valuenow</span><span class="o">=</span><span class="dl">"</span><span class="s2">0</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">valuemin</span><span class="o">=</span><span class="dl">"</span><span class="s2">0</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">valuemax</span><span class="o">=</span><span class="dl">"</span><span class="s2">100</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-progress-bar-selector qq-progress-bar</span><span class="dl">"</span><span class="o">><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-spinner-selector qq-upload-spinner</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-thumbnail-wrapper</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">img</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-thumbnail-selector</span><span class="dl">"</span> <span class="nx">qq</span><span class="o">-</span><span class="nx">max</span><span class="o">-</span><span class="nx">size</span><span class="o">=</span><span class="dl">"</span><span class="s2">120</span><span class="dl">"</span> <span class="nx">qq</span><span class="o">-</span><span class="nx">server</span><span class="o">-</span><span class="nx">scale</span><span class="o">></span>
<span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-cancel-selector qq-upload-cancel</span><span class="dl">"</span><span class="o">></span><span class="nx">X</span><span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-retry-selector qq-upload-retry</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-retry-icon</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">label</span><span class="o">=</span><span class="dl">"</span><span class="s2">Retry</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="nx">Retry</span>
<span class="o"><</span><span class="sr">/button</span><span class="err">>
</span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-file-info</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-file-name</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-file-selector qq-upload-file</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-edit-filename-icon-selector qq-edit-filename-icon</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">label</span><span class="o">=</span><span class="dl">"</span><span class="s2">Edit filename</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">input</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-edit-filename-selector qq-edit-filename</span><span class="dl">"</span> <span class="nx">tabindex</span><span class="o">=</span><span class="dl">"</span><span class="s2">0</span><span class="dl">"</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-upload-size-selector qq-upload-size</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-upload-delete-selector qq-upload-delete</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-delete-icon</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">label</span><span class="o">=</span><span class="dl">"</span><span class="s2">Delete</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-upload-pause-selector qq-upload-pause</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-pause-icon</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">label</span><span class="o">=</span><span class="dl">"</span><span class="s2">Pause</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-upload-continue-selector qq-upload-continue</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">span</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-btn qq-continue-icon</span><span class="dl">"</span> <span class="nx">aria</span><span class="o">-</span><span class="nx">label</span><span class="o">=</span><span class="dl">"</span><span class="s2">Continue</span><span class="dl">"</span><span class="o">><</span><span class="sr">/span</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/li</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/ul</span><span class="err">>
</span>
<span class="o"><</span><span class="nx">dialog</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-alert-dialog-selector</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-dialog-message-selector</span><span class="dl">"</span><span class="o">><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-dialog-buttons</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-cancel-button-selector</span><span class="dl">"</span><span class="o">></span><span class="nx">Close</span><span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/dialog</span><span class="err">>
</span>
<span class="o"><</span><span class="nx">dialog</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-confirm-dialog-selector</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-dialog-message-selector</span><span class="dl">"</span><span class="o">><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-dialog-buttons</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-cancel-button-selector</span><span class="dl">"</span><span class="o">></span><span class="nx">No</span><span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-ok-button-selector</span><span class="dl">"</span><span class="o">></span><span class="nx">Yes</span><span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/dialog</span><span class="err">>
</span>
<span class="o"><</span><span class="nx">dialog</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-prompt-dialog-selector</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-dialog-message-selector</span><span class="dl">"</span><span class="o">><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">div</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-dialog-buttons</span><span class="dl">"</span><span class="o">></span>
<span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-cancel-button-selector</span><span class="dl">"</span><span class="o">></span><span class="nx">Cancel</span><span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="nx">button</span> <span class="nx">type</span><span class="o">=</span><span class="dl">"</span><span class="s2">button</span><span class="dl">"</span> <span class="kd">class</span><span class="o">=</span><span class="dl">"</span><span class="s2">qq-ok-button-selector</span><span class="dl">"</span><span class="o">></span><span class="nx">Ok</span><span class="o"><</span><span class="sr">/button</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/dialog</span><span class="err">>
</span> <span class="o"><</span><span class="sr">/div</span><span class="err">>
</span><span class="nt"></script></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"fine-uploader-gallery"</span> <span class="na">data-post-url=</span><span class="s">"<%= data_post_link %>"</span> <span class="na">data-input-name=</span><span class="s">"<%= input_name %>"</span> <span class="na">data-delete-endpoint=</span><span class="s">"<%= delete_endpoint %>"</span><span class="nt">></div></span>
</code></pre></div>
<p>Yukarıdaki kodlarda son satır bizim <code>coffeescript</code> kodları ile bağlantımızı yapan kısımdır. Artık bu noktadan sonra bu
dosyayı nereden render edersek orada fineuploader'ı kullanabiliriz. Peki bu satırdaki dataları neden <code>coffeescript</code>
tarafına gönderiyoruz? Bunun cevabını şu şekilde açıklayabilirim: <code>post-url</code> yüklenen dosyanın gideceği endpointi
belirlemek için, <code>input-name</code> dosyalarınızı strong parametreden geçirebilmeniz için gereken parametre ismini
düzenleyebilmeniz için, <code>delete-endpoint</code> ise eğer yüklenen dosyalarınızda delete özelliğini kullanmak isterseniz
yapılacak olan isteğin gideceği endpointi belirlememizi sağlaması için bu dataları gönderiyoruz.</p>
<p>Şimdi gelelim `coffeescript kodlarına:</p>
<div class="highlight"><pre class="highlight coffeescript"><code> <span class="nx">$</span><span class="p">(</span><span class="s">'#fine-uploader-gallery'</span><span class="p">).</span><span class="na">fineUploader</span>
<span class="na">template</span><span class="o">:</span> <span class="s">'qq-template-gallery'</span>
<span class="na">request</span><span class="o">:</span>
<span class="na">inputName</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s">'#fine-uploader-gallery'</span><span class="p">).</span><span class="na">data</span><span class="p">(</span><span class="s">'input-name'</span><span class="p">)</span>
<span class="na">endpoint</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s">'#fine-uploader-gallery'</span><span class="p">).</span><span class="na">data</span><span class="p">(</span><span class="s">'post-link'</span><span class="p">)</span>
<span class="na">deleteFile</span><span class="o">:</span>
<span class="na">enabled</span><span class="o">:</span> <span class="no">true</span><span class="p">,</span>
<span class="na">confirmMessage</span><span class="o">:</span> <span class="s">"{filename} isimli fotoğrafı silmek istediğinize emin misiniz?"</span>
<span class="na">endpoint</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s">'#fine-uploader-gallery'</span><span class="p">).</span><span class="na">data</span><span class="p">(</span><span class="s">'delete-endpoint'</span><span class="p">)</span>
<span class="na">retry</span><span class="o">:</span>
<span class="na">enableAuto</span><span class="o">:</span> <span class="no">true</span>
<span class="na">messages</span><span class="o">:</span>
<span class="na">tooManyItemsError</span><span class="o">:</span> <span class="s">"({netItems}) adet fotoğraf, yüklemek için çok fazla. En Fazla {itemLimit} adet fotoğraf yükleyebilirsiniz."</span>
<span class="na">callbacks</span><span class="o">:</span>
<span class="na">onComplete</span><span class="o">:</span> <span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">xhr</span><span class="p">)</span> <span class="o">-></span>
<span class="o">*</span> <span class="nx">kodlar</span> <span class="nx">buraya</span> <span class="nx">gelecek</span>
<span class="na">onProgress</span><span class="o">:</span> <span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">fileName</span><span class="p">,</span> <span class="nx">loaded</span><span class="p">,</span> <span class="nx">total</span><span class="p">)</span> <span class="o">-></span>
<span class="o">*</span> <span class="nx">kodlar</span> <span class="nx">buraya</span> <span class="nx">gelecek</span>
<span class="na">onAllComplete</span><span class="o">:</span> <span class="p">()</span> <span class="o">-></span>
<span class="o">*</span> <span class="nx">kodlar</span> <span class="nx">buraya</span> <span class="nx">gelecek</span>
<span class="na">failedUploadTextDisplay</span><span class="o">:</span> <span class="na">mode</span><span class="o">:</span> <span class="s">'custom'</span>
<span class="na">thumbnails</span><span class="o">:</span> <span class="na">placeholders</span><span class="o">:</span>
<span class="na">waitingPath</span><span class="o">:</span> <span class="s">'/fine_uploader/waiting-generic.png'</span>
<span class="na">notAvailablePath</span><span class="o">:</span> <span class="s">'/fine_uploader/not_available-generic.png'</span>
<span class="na">validation</span><span class="o">:</span>
<span class="na">itemLimit</span><span class="o">:</span> <span class="mi">10</span>
<span class="na">scaling</span><span class="o">:</span>
<span class="na">sendOriginal</span><span class="o">:</span> <span class="no">false</span>
<span class="na">sizes</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span>
<span class="na">maxSize</span><span class="o">:</span> <span class="mi">1000</span>
<span class="p">}</span> <span class="p">]</span>
</code></pre></div>
<p>Yukarıdaki kodlar projelerde kullandığım özellikleri içeren kodlardır. Sizlere bunları açıklayacağım, Fineuploader'da
bunun gibi bir çok özellik bulunmaktadır, web sayfasına gidip diğer özellikleri de öğrenebilirsiniz.</p>
<ul>
<li><strong>request:</strong> Yüklenen dosyaların inputName'ini ve endpoint'ini belirtiyoruz bu sayede fotoğrafı istediğimiz yere istediğimiz
parametre ismi ile gönderebiliriz.</li>
<li><strong>deleteFile:</strong> Delete özelliğini kullanmak isterseniz bu option işinizi görecektir fakat default olarak istek ‘uuid’
ile yapılmaktadır eğer ‘uuid’ yerine başka bir parametre ile bu isteği yapmak isterseniz ‘onComplaete’ callback'inin
içinde kullanacağımız ‘setUuid’ metodu işinizi görecektir.
‘enable’ ile yüklenen dosyanın silinmesini etkinleştiririz veya devredışı bırakırız. ‘confirmMessage’ ile default
mesajı değiştirebilmemizi sağlar. ‘endpoint’ ile yapılacak olan isteğin gideceği yeri ayarlamamızı sağlar. </li>
<li><strong>retry:</strong> Bu option ile ‘enableAuto: true’ yaptığınız zaman eğer olurda dosya yüklenmez ise otomatik olarak dosya
3 kere daha yüklenmeyi dener yine olmaz ise yükleme isteği kesilir.</li>
<li><strong>messages:</strong> Fineuploader'da bulunan default mesajları değiştirebilmemizi sağlar. Yukarıda bir adet örneğini görüyorsunuz.</li>
<li><strong>callbacks:</strong> Fineuploader da çok kullanışlı callback'ler vardır yukarıda bunlardan birkaç tanesini görüyorsunuz.
onComplete: yüklenen her dosya sonrasında çalışır, onProgress: tüm dosyaların yükleme işlemi devam ettiği
sürece çalışır, onAllComplate: tüm dosyaların yükleme işlemi bittiğinde çalışır.</li>
<li><strong>failedUploadTextDisplay:</strong> Bu option ile başarısız olan yükleme dosyaları için çıkan default mesajı
‘mode: 'custom’ yaparak dosya yüklendikten sonra döndüreceğiniz json dosyasında ‘message’ parametresi ile değiştirebilirsiniz.</li>
<li><strong>thumbnails:</strong> Option'ında ‘placeholders’ ile dosya hazırlanırken veya ulaşılamazken çıkacak resimler ayarlanır.</li>
<li><strong>validation:</strong> Bu option ile validasyonları kullanabiliriz. Mesela yukarıda ‘itemLimit’ validasyonu yer almaktadır.
Bu validasyon ile Fineuploader ile bir anda 10 adet dosya yüklenebilir.</li>
<li><strong>scaling:</strong> Bu option Fineuploader'ın bizlere sunduğu en önemli özelliklerden bir tanesi diyebilirim.
Bu option ile yüklenen fotoğrafların boyutlarını ölçeklendirebilirsiniz, bu işlemi çok hızlı bir şekilde yapmaktadır.
Yukarıda yüklenen fotoğrafın ‘sendOriginal: false’ ile ölçeklendirilmiş hali gönderilmektedir.
‘maxSize: 1000’ ile uzun kenar maksimum 1000 piksel olacak şekilde ayarlanmıştır. Fakat ‘scaling’ option'ında
ölçeklendirilen fotoğrafların isimleri ‘Blob’ olarak gönderilmektedir. Tabi fotoğrafın orjinal ismi de gönderilmektedir,
orginal ismi ile gönderilen ismi yer değiştirip fotoğrafın orjinal ismini kullanabilirsiniz. </li>
</ul>
<p>Sizlere Fineuploader'ın ne olduğundan ve Rails'de kullanımından kısaca bahsettim.
Fineuploader sürekli güncellenmekte ve desteklenmektedir.
Fineuploader'ın daha birçok özelliğini web sayfasını kurcalayarak öğrenebilir ve kullanabilirsiniz. </p>
<p><a href="https://fineuploader.com"> Bu adresten </a> web sayfasını inceleyebilirsiniz.</p>
<p>Bu yazının sizlere faydalı olması dileğiyle…</p>
Arayüz Tasarımcıları ve Geliştiriciler için Collaboration Araçları - Invision, Redpen ve Zeplin
http://lab2023.com/arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari.html
2017-02-17T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhaba,</p>
<p>Front-end ve Back-end geliştiricilerin ağırlıklı kullandığı github, gitlab, bitbucket gibi araçlar, birlikte çalışma
ortamı yaratarak kendilerini collaborative (işbirliği) ile geliştirme ortamı yaratma konusunda etkili, verimli sistemlerdir.</p>
<p>Arayüz tasarımcılarını ele aldığımızda karşımıza, tasarlama, tasarımı teslim etme ve tasarımı geliştirme adına geliştiriciler
ve firmalar için hayatı kolaylaştırma adına uygulamalar karşımıza çıkıyor. Bunlardan en fazla işimize yarayabilecekleri birlikte
inceleyerek uygun platformu seçebiliriz.</p>
<h2 id="1-invisionapp">1. InvisionApp</h2>
<p><img alt="invision" src="assets/images/articles/2017-02-17-arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari/invision-logo-square.png" /></p>
<p>İnvisionapp diğer uygulamalara göre biraz daha kendini geliştirmiş diyebiliriz. Yaptığı işler ile adından söz ettirmemesi
sürpriz olurdu.</p>
<p><img alt="invision" src="assets/images/articles/2017-02-17-arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari/mockup-2.png" /></p>
<p>3 ayrı özellik prototyping, collaboration ve workflow platformu olarak ele almamız doğru olur.Invision üzerinden tasarım
yapabilirken, aynı zaman da çalışma arkadaşlarınız ile birlikte çalışmanın herhangi bir noktasına yorum bırakabiliriz.</p>
<p><img alt="invision" src="assets/images/articles/2017-02-17-arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari/mockup-5.png" /></p>
<p>Bu platformun güzel tarafı realtime olarak collaboration sunması. Board kullanarak tasarımlarınızı, tüm takım arkadaşları
ile birlikte editleme ve yorumlama imkanınız oluyor.Ayrıca tüm tasarım sayfalarınızı tek bir layout üzerinde sunum dosyası
oluşturarak inceleyebilirsiniz. Built-in layout sistemi yardımıyla tüm tasarımı styleguide ile birlikte sunum haline getirerek,
takım arkadaşlarınıza görsel bir zenginlik sağlar.</p>
<p>Diğer bir yandan <strong>dropbox, drive, slack, basecamp, trello, jira, github, hipchat</strong> gibi platformlar ile uyumlu çalışarak
push & pull işlemini otomatik olarak sizin yerinize gerçekleştirir.</p>
<p>Başlangıç paketine yıllık üyelik durumunda %10 indirimle ayda 13 dolar, team paketine yine aynı kural dahilinde 89 dolardan
sahip olabilirsiniz.</p>
<h2 id="2-redpen-io">2. Redpen.io</h2>
<p><img alt="redpen" src="assets/images/articles/2017-02-17-arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari/upload.png" /></p>
<p>Redpen, collaboration platformları arasında özellikleri bakımından kısıtlı ama bir o kadar hızlı uygulamadır.</p>
<p>Drag&drop özelliği ile projelerinizi kolayca platforma entegre edebilir, proje olarak klasörleyebilir, işlerinizi daha
organize yönetebilirsiniz.</p>
<p>Diğer platformlarda olduğu gibi redpen de realtime olarak takım yorumları ve incelemesinde bulunabilirsiniz.
Üzerinde herhangi bir düzenlemeye izin vermediği için müşterilere tasarımlarınızı sunabilirsiniz.Yapılan comment
altına istediğiniz kadar comment atabilme imkanınız da bulunuyor.Fakat unutmayın redpen size 2 haftalık deneme sürümü sunuyor.
Proje bazlı fiyatlandırması olan platform 20 dolar gibi başlangıç fiyatıyla rakiplerine biraz fazla şans tanıyor gibi. </p>
<h2 id="3-zeplin">3. Zeplin</h2>
<p><img alt="zeplin" src="assets/images/articles/2017-02-17-arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari/zeplin-logo.png" /></p>
<p>Sunduğu özellikler bakımından aralarında en hızlı, kolay ve kullanışlı gördüğüm platform diyebiliriz.Tasarımları teslim
ederken size sunduğu özellikler cezbedebilir, aynı zamanda çalışmalarınızda da büyük kolaylık sağlayabilir.</p>
<p>Hem Sketch hem de Photoshop ile yaptığınız tasarımları kolayca senkronize ederek export edebilirsiniz.</p>
<p><img alt="zeplin" src="assets/images/articles/2017-02-17-arayuz-tasarimlari-ve-gelistiriciler-icin-collaboration-araclari/zeplin.jpg" /></p>
<p>Bir diğer iyi yanı, tasarımda kullanılan assets, bitmap ve style özelliklerini çalışma arkadaşlarınız ile paylaşarak
çalışma ortamına aktarabilirsiniz.</p>
<p>Diğer platformlarda olduğu gibi bu platform da comment özelliği ile takım olarak tasarımı inceleme olanağına sahip.</p>
<p>Front-end geliştiricileri de düşünerek tasarım üzerinde seçtiğiniz objenin HTML/CSS (css,sass,less,stylus vb.)
kodlarını görebilmeniz mümkün.</p>
<p>Yakın zamanda yayınladıkları yeni özellik versiyonlama ile zaman içinde export edilen dosyaların saklanmasında
yardımcı oluyor.</p>
<p>Tek bir proje üzerinde çalışma yapmak isteyenler için Zeplin ücretsiz destek veriyor fakat 3 proje için
17, 12 proje için 26 dolar gibi bir fiyatlandırması mevcut.Ekip ya da firma olarak kullanmak isterseniz kullanıcı
başına 6-7 dolar civarı bir miktar yeterli oluyor.</p>
<p>Bir sonraki yazıda Wake ve Lingoapp üzerine inceleme yapacağız.</p>
Rails 5'de Dinamik Nested Form Kullanımı
http://lab2023.com/rails-5-de-dinamik-nested-form-kullanimi.html
2017-02-10T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhabalar,</p>
<p>Bu yazıda sizelere Rails'de dinamik nested form kullanımını bir örnek ile göstereceğim. Eğer birbiri ile ilişkili iki
modeliniz var ise ve tek bir form üzerinden kayıt yapacaksanız nested form kullanmanız gerekiyor.
Şimdi öncelikle aşağıdaki gibi birbiri ile ilişkili iki modelinizin olduğu bir rails projeniz olduğunu varsayalım.
İlişki şekli şu şekilde olsun Customer(Müşteri) ve Customer'ın AuthorizedPerson(YetkiliKişi)‘ları.</p>
<p>Aşağıda <code>accepts_nested_attributes_for</code>ile nested attribute ilişkiyi kuruyoruz;</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1"># app/models/customer.rb</span>
<span class="n">has_many</span> <span class="ss">:authorized_persons</span><span class="p">,</span> <span class="ss">dependent: :destroy</span>
<span class="n">accepts_nested_attributes_for</span> <span class="ss">:authorized_persons</span><span class="p">,</span> <span class="ss">allow_destroy: </span><span class="kp">true</span>
<span class="c1"># app/models/authorized_person.rb</span>
<span class="n">belongs_to</span> <span class="ss">:customer</span><span class="p">,</span> <span class="ss">optional: </span><span class="kp">true</span>
</code></pre></div>
<p>Strong parametrelerimizi aşağıdaki gibi ayarlıyoruz. Burada <code>authorized_persons_attributes</code> ile AuthorizedPerson için gelen verilerin geçmesine izin veriyoruz.</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1">#app/controllers/customers_controller.rb</span>
<span class="k">def</span> <span class="nf">customer_params</span>
<span class="n">params</span><span class="p">.</span><span class="nf">require</span><span class="p">(</span><span class="ss">:customer</span><span class="p">).</span><span class="nf">permit</span><span class="p">(</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">authorized_persons_attributes: </span><span class="p">[</span><span class="ss">:id</span><span class="p">,</span> <span class="ss">:email</span><span class="p">,</span> <span class="ss">:_destroy</span><span class="p">])</span>
<span class="k">end</span>
</code></pre></div>
<p>formumuzu aşağıdaki gibi oluşturuyoruz, aşağıdaki <code>fields_for</code> kısmı nested formda ilgili diğer modelimizin alanlarını eklemek için gerekli alandır. </p>
<div class="highlight"><pre class="highlight ruby"><code><span class="o">=</span> <span class="n">simple_form_for</span><span class="p">(</span><span class="vi">@customer</span><span class="p">,</span> <span class="ss">validate: </span><span class="kp">true</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="p">.</span><span class="nf">form</span><span class="o">-</span><span class="n">inputs</span>
<span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">input</span> <span class="ss">:name</span>
<span class="o">=</span> <span class="n">link_to_add_fields</span> <span class="s1">'Add Authorized People'</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="ss">:authorized_persons</span>
<span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">fields_for</span> <span class="ss">:authorized_persons</span> <span class="k">do</span> <span class="o">|</span><span class="n">builder</span><span class="o">|</span>
<span class="o">=</span> <span class="n">render</span> <span class="s1">'authorized_person_fields'</span><span class="p">,</span> <span class="ss">f: </span><span class="n">builder</span>
<span class="p">.</span><span class="nf">form</span><span class="o">-</span><span class="n">actions</span>
<span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">button</span> <span class="ss">:submit</span>
</code></pre></div>
<p>Helper dosyamıza aşağıdaki kodları koyuyoruz:</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1">#app/helpers/application_helper.rb</span>
<span class="k">def</span> <span class="nf">link_to_add_fields</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">association</span><span class="p">)</span>
<span class="n">new_object</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">object</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">association</span><span class="p">).</span><span class="nf">klass</span><span class="p">.</span><span class="nf">new</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">new_object</span><span class="p">.</span><span class="nf">object_id</span>
<span class="n">fields</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">fields_for</span><span class="p">(</span><span class="n">association</span><span class="p">,</span> <span class="n">new_object</span><span class="p">,</span> <span class="ss">child_index: </span><span class="nb">id</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">builder</span><span class="o">|</span>
<span class="n">render</span><span class="p">(</span><span class="n">association</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">singularize</span> <span class="o">+</span> <span class="s1">'_fields'</span><span class="p">,</span> <span class="ss">f: </span><span class="n">builder</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">link_to</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="ss">class: </span><span class="s1">'add_fields'</span><span class="p">,</span> <span class="ss">data: </span><span class="p">{</span><span class="ss">id: </span><span class="nb">id</span><span class="p">,</span> <span class="ss">fields: </span><span class="n">fields</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="s1">'\n'</span><span class="p">,</span> <span class="s1">''</span><span class="p">)})</span>
<span class="k">end</span>
</code></pre></div>
<p><code>_authorized_person_fields</code> dosyamız aşağıdaki gibidir.</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1">#app/views/customers/_authorized_person_fields.html.haml</span>
<span class="o">%</span><span class="n">fieldset</span>
<span class="o">=</span> <span class="n">link_to</span> <span class="s1">'Remove Authorized People'</span><span class="p">,</span> <span class="s1">'#'</span><span class="p">,</span> <span class="ss">class: </span><span class="s1">'remove_fields'</span>
<span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">input</span> <span class="ss">:email</span>
<span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">hidden_field</span> <span class="ss">:_destroy</span>
</code></pre></div>
<p>coffescript dosyamıza da aşağıdaki kodlarımızı koyuyoruz:</p>
<div class="highlight"><pre class="highlight javascript"><code><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span> <span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">form .remove_fields</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">-></span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">prev</span><span class="p">(</span><span class="dl">'</span><span class="s1">input[type=hidden]</span><span class="dl">'</span><span class="p">).</span><span class="nx">val</span><span class="p">(</span><span class="dl">'</span><span class="s1">1</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">closest</span><span class="p">(</span><span class="dl">'</span><span class="s1">fieldset</span><span class="dl">'</span><span class="p">).</span><span class="nx">remove</span><span class="p">()</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">()</span>
<span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span> <span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">form .add_fields</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">-></span>
<span class="nx">time</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">()</span>
<span class="nx">regexp</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">data</span><span class="p">(</span><span class="dl">'</span><span class="s1">id</span><span class="dl">'</span><span class="p">),</span> <span class="dl">'</span><span class="s1">g</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">before</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">data</span><span class="p">(</span><span class="dl">'</span><span class="s1">fields</span><span class="dl">'</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="nx">regexp</span><span class="p">,</span> <span class="nx">time</span><span class="p">))</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">()</span>
</code></pre></div>
<p>Yukarıda yaptığımız işlemler ile aşağıdaki gibi bir çıktı elde edeceksiniz:</p>
<p><img alt="form" width="384" height="121" src="assets/images/articles/2017-02-10-rails-dynamic-nested-form.png" /></p>
Rails'de ActionCable nedir ve nasıl kullanılır?
http://lab2023.com/rails-5-de-action-cable-nedir-ve-nasil-kullanilir.html
2017-02-03T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<h1 id="websocket-nedir">Websocket nedir?</h1>
<p>websocket TCP üzerine kurulu HTTP gibi bir protokoldür ve HTML5 ile birlikte gelerek HTTP protokolünün gerçek zamanlı uygulamalardaki eksiklerini kapatmıştır. HTTP request/response mantığı üzerinde kurulu protokoldür yani client tarafından bir istek yapılır ve server tarafından bu isteğe cevap beklenir, durum böyle olunca istek yapmayan clientlar bu requesti alamamaktaydı bu durumda chat uygulamaları gibi gerçek zamanlı uygulamalarda büyük bir problem oluşturmaktaydı. Websocketten önce bu problem belirli aralıklarda ajax ile client tarafına sunucu tarafından istek yaparak değişiklikleri göndererek kısmen çözülebiliyordu fakat bu işlem gereksiz veri transferlerine ve yavaşlamaya neden olmaktaydı, websocket ile birlikte bu problemin önüne geçildi yani websocket HTTP’nin aksine kanallar aracılığı ile server tarafında herhangi bir değişiklik olduğunda sadece istek yapan client’a değil kanala bağlı tüm clientlara ilgili değişikliği göndermektedir böylece aradaki bağlantı hiç kopartılmadan gerçek zamanlı olarak sadece yapılan değişiklikler gönderilmiş olur.</p>
<h1 id="actioncable-nedir">ActionCable nedir?</h1>
<p>Action Cable Rails-5 ile gelen ve websocket kullanabilmemiz için geliştirilmiş olan bir kütüphanedir, RailsConf 2015'te duyurulmuştur. Action Cable bize server tarafta ruby ile client tarafta ise javascript ile full-stack bir yapı sunar. Active Record veya ORM modeli ile yazdığımız modellerimize erişebiliriz. Action Cable bir mesajlaşma pattern’ı olan Publisher/Subscriber yaklaşımı kullanarak server ve clientlar arasında bağlantı sağlar.</p>
<h2 id="rnek-uygulama">Örnek Uygulama:</h2>
<p>Teknik detayları aşağıda bulunan DHH’nin örneği üzerinden açıklayacağım.</p>
<p>Öncelikle sırasıyla aşağıdaki işlemleri yapıp uygulamamızı hazırlıyoruz.</p>
<p>Uygulamayı oluşturma:
<code>ruby
rails new chat --skip-spring
</code></p>
<p>Room adlı controllerımızı oluşturuyoruz:
<code>ruby
rails g controller rooms show
</code></p>
<p>Database’imizi ve Message modelimizi oluşturuyoruz:
<code>
rails db:create
rails g model message content:text
rails db:migrate
</code></p>
<p>Message tablomuza yeni bir kayıt oluşturuyoruz:
<code>ruby
Message.create(content: 'hello world')
</code></p>
<p>Son olarak da root dosyamızı düzenliyoruz:
<code>ruby
root to: 'rooms#show'
</code></p>
<p>Controllerımızı ve view sayfalarımızı aşağıdaki gibi güncelliyoruz:
“`ruby</p>
<h1 id="app-controllers-rooms_controller-rb">app/controllers/rooms_controller.rb</h1>
<p>class RoomsController < ApplicationController
def show
@messages = Message.all
end
end
”`</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1"># app/views/rooms/show.html.erb</span>
<span class="o"><</span><span class="n">h1</span><span class="o">></span><span class="no">Chat</span> <span class="n">room</span><span class="o"><</span><span class="sr">/h1>
<div id="messages">
<%= render @messages %>
</</span><span class="n">div</span><span class="o">></span>
<span class="o"><</span><span class="n">form</span><span class="o">></span>
<span class="o"><</span><span class="n">label</span><span class="o">></span><span class="no">Say</span> <span class="n">something</span><span class="ss">:<</span><span class="o">/</span><span class="n">label</span><span class="o">><</span><span class="n">br</span><span class="o">></span>
<span class="o"><</span><span class="n">input</span> <span class="n">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="n">data</span><span class="o">-</span><span class="n">behavior</span><span class="o">=</span><span class="s2">"room_speaker"</span><span class="o">></span>
<span class="o"><</span><span class="sr">/form>
</span></code></pre></div><div class="highlight"><pre class="highlight ruby"><code><span class="c1"># app/view/messages/_message.html.erb</span>
<span class="o"><</span><span class="n">div</span> <span class="k">class</span><span class="o">=</span><span class="err">“</span><span class="n">message</span><span class="err">”</span><span class="o">></span>
<span class="o"><</span><span class="nb">p</span><span class="o">><</span><span class="sx">%= message.content %></p>
</div>
</span></code></pre></div>
<p>ve <em>‘rails s’</em> diyip uygulamanın <em><a href="http://localhost:3000/">http://localhost:3000/</a></em>’dan kullanıcı tarafındaki görüntüsünü görebiliriz.</p>
<p>ActionCable tarafı için şu işlemleri yapıyoruz:</p>
<p><em>config/routes.rb</em> dosyamıza aşağıdaki satırı koyarak ActionCable’ı monte ediyoruz.
<code>ruby
mount ActionCable.server => '/cable'
</code></p>
<p>Rails projesinin oluşturulması ile birlikte oluşan <em>javascript/cable.js</em> dosyamız şu şekildedir:</p>
<div class="highlight"><pre class="highlight javascript"><code><span class="c1">//= require action_cable</span>
<span class="c1">//= require_self</span>
<span class="c1">//= require_tree ./channels</span>
<span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">App</span> <span class="o">||</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">App</span> <span class="o">=</span> <span class="p">{});</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">cable</span> <span class="o">=</span> <span class="nx">ActionCable</span><span class="p">.</span><span class="nx">createConsumer</span><span class="p">();</span>
<span class="p">}).</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</code></pre></div>
<p>Route dosyamıza yukarıdaki satırı ekledikten sonra browser console'umuzdan <em>“App.cable”</em> ı yazdığımızda aşağıdaki sonucu alabilmeniz gerekiyor.</p>
<div class="highlight"><pre class="highlight javascript"><code><span class="nx">Consumer</span> <span class="p">{</span><span class="nl">url</span><span class="p">:</span> <span class="dl">"</span><span class="s2">ws://localhost:3000/cable</span><span class="dl">"</span><span class="p">,</span> <span class="nx">subscriptions</span><span class="p">:</span> <span class="nx">Subscriptions</span><span class="p">,</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">}</span>
</code></pre></div>
<p>Artık örneğimiz için kanal oluşturma zamanı geldi.</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">rails</span> <span class="n">g</span> <span class="n">channel</span> <span class="n">room</span> <span class="n">speak</span>
</code></pre></div>
<p>ile birlikte iki adet yeni dosyamız oluşacak: javascript tarafı için <em>app/assets/javascripts/channels/room.coffee</em> dosyası ve ruby tarafı için <em>app/channels/room_channel.rb</em> dosyası oluşacak.</p>
<p>Dosyalarımız başlangıçta şu şekildedir: </p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1">#app/channels/room_channel.rb </span>
<span class="k">class</span> <span class="nc">RoomChannel</span> <span class="o"><</span> <span class="no">ApplicationCable</span><span class="o">::</span><span class="no">Channel</span>
<span class="k">def</span> <span class="nf">subscribed</span>
<span class="c1"># stream_from "some_channel" </span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">unsubscribed</span>
<span class="c1"># Any cleanup needed when channel is unsubscribed </span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">speak</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p><em>‘subscriber’</em> ve <em>‘unsubscriber’</em> ActionCable’ın default callback’leridir.</p>
<div class="highlight"><pre class="highlight javascript"><code><span class="err">#</span><span class="nx">app</span><span class="o">/</span><span class="nx">assets</span><span class="o">/</span><span class="nx">javascripts</span><span class="o">/</span><span class="nx">channels</span><span class="o">/</span><span class="nx">room</span><span class="p">.</span><span class="nx">coffee</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">room</span> <span class="o">=</span> <span class="nx">App</span><span class="p">.</span><span class="nx">cable</span><span class="p">.</span><span class="nx">subscriptions</span><span class="p">.</span><span class="nx">create</span> <span class="dl">"</span><span class="s2">RoomChannel</span><span class="dl">"</span><span class="p">,</span>
<span class="nx">connected</span><span class="p">:</span> <span class="o">-></span>
<span class="err">#</span> <span class="nx">Called</span> <span class="nx">when</span> <span class="nx">the</span> <span class="nx">subscription</span> <span class="nx">is</span> <span class="nx">ready</span> <span class="k">for</span> <span class="nx">use</span> <span class="nx">on</span> <span class="nx">the</span> <span class="nx">server</span>
<span class="nx">disconnected</span><span class="p">:</span> <span class="o">-></span>
<span class="err">#</span> <span class="nx">Called</span> <span class="nx">when</span> <span class="nx">the</span> <span class="nx">subscription</span> <span class="nx">has</span> <span class="nx">been</span> <span class="nx">terminated</span> <span class="nx">by</span> <span class="nx">the</span> <span class="nx">server</span>
<span class="nx">received</span><span class="p">:</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">-></span>
<span class="err">#</span> <span class="nx">Called</span> <span class="nx">when</span> <span class="nx">there</span><span class="dl">'</span><span class="s1">s incoming data on the websocket for this channel
speak: ->
@perform </span><span class="dl">'</span><span class="nx">speak</span><span class="dl">'</span><span class="s1">
</span></code></pre></div>
<p><em>connected</em> methodu kanal ile ilk bağlantı oluşturulduğunda çalışan methotdur, <em>received</em> methodu ise veri geldiğinde çalışan fonksiyondur. <em>speak</em> methodu ise clienttan gelen veriyi <em>room_channel.rb</em>’nin içindeki <em>speak</em> fonksiyonuna gönderdiğimiz methoddur.</p>
<p>Daha sonra veri iletimini gerçekleştirmek için dosyalarımızı şu şekilde göncelliyoruz:</p>
<div class="highlight"><pre class="highlight javascript"><code><span class="err">#</span><span class="nx">app</span><span class="o">/</span><span class="nx">assets</span><span class="o">/</span><span class="nx">javascripts</span><span class="o">/</span><span class="nx">channels</span><span class="o">/</span><span class="nx">room</span><span class="p">.</span><span class="nx">coffee</span>
<span class="nx">received</span><span class="p">:</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">-></span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#messages</span><span class="dl">'</span><span class="p">).</span><span class="nx">append</span> <span class="nx">data</span><span class="p">[</span><span class="dl">'</span><span class="s1">message</span><span class="dl">'</span><span class="p">]</span>
<span class="nx">speak</span><span class="p">:</span> <span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="o">-></span>
<span class="p">@</span><span class="nd">perform</span> <span class="dl">'</span><span class="s1">speak</span><span class="dl">'</span><span class="p">,</span> <span class="nx">message</span><span class="p">:</span> <span class="nx">message</span>
<span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span> <span class="dl">'</span><span class="s1">keypress</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">[data-behavior~=room_speaker]</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">-></span>
<span class="k">if</span> <span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span> <span class="nx">is</span> <span class="mi">13</span> <span class="err">#</span> <span class="k">return</span><span class="sr">/enter = sen</span><span class="err">d
</span> <span class="nx">App</span><span class="p">.</span><span class="nx">room</span><span class="p">.</span><span class="nx">speak</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="dl">''</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">()</span>
</code></pre></div><div class="highlight"><pre class="highlight ruby"><code><span class="c1">#app/channels/room_channel.rb</span>
<span class="k">def</span> <span class="nf">speak</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="no">Message</span><span class="p">.</span><span class="nf">create!</span> <span class="ss">content: </span><span class="n">data</span><span class="p">[</span><span class="s1">'message'</span><span class="p">]</span>
<span class="k">end</span>
</code></pre></div>
<p>modelimizin içini bu şekilde güncelliyoruz.</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1">#app/models/message.rb</span>
<span class="k">class</span> <span class="nc">Message</span> <span class="o"><</span> <span class="no">ApplicationRecord</span>
<span class="n">after_create_commit</span> <span class="p">{</span> <span class="no">MessageBroadcastJob</span><span class="p">.</span><span class="nf">perform_later</span> <span class="nb">self</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre></div>
<p>daha sonra Job’ımızı oluşturuyoruz:</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">rails</span> <span class="n">g</span> <span class="n">job</span> <span class="no">MessageBroadcast</span>
</code></pre></div>
<p>ve içini bu şekilde güncelliyoruz:</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="k">class</span> <span class="nc">MessageBroadcastJob</span> <span class="o"><</span> <span class="no">ApplicationJob</span>
<span class="n">queue_as</span> <span class="ss">:default</span>
<span class="k">def</span> <span class="nf">perform</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="no">ActionCable</span><span class="p">.</span><span class="nf">server</span><span class="p">.</span><span class="nf">broadcast</span> <span class="s1">'room_channel'</span><span class="p">,</span> <span class="ss">message: </span><span class="n">render_message</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">end</span>
<span class="kp">private</span>
<span class="k">def</span> <span class="nf">render_message</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="no">ApplicationController</span><span class="p">.</span><span class="nf">renderer</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="ss">partial: </span><span class="s1">'messages/message'</span><span class="p">,</span> <span class="ss">locals: </span><span class="p">{</span> <span class="ss">message: </span><span class="n">message</span> <span class="p">})</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>İşlemlerimizi tamamladıktan sonra burada işleyen işlemi anlatmanın vakti geldi. Bu uygulama ActionCable’ın mantığını anlatmak adına tek odalı bir chat uygulaması için yapılmış bir uygulamadır istenilirse kod geliştirilerek çok odalı bir chat uygulaması yapılabilir. Uygulamada kullanıcı ‘Say Something:’ kısmından girdiği yazıyı entera basarak gönderir ve server tarafına gelen mesaj <em>#app/assets/javascripts/channels/room.coffee</em> dosyasının en altında bulunan javascript fonksiyonu ile yakalanır ve yine aynı klasörde bulunan <em>speak</em> methoduna gönderilir, bu dosyadaki <em>speak</em> methodu <em>#app/channels/room_channel.rb</em> dosyasındaki <em>speak</em> methoduna gelen data <em>message</em> olarak gönderilir. <em>#app/channels/room_channel.rb</em> dosyasında bulunan <em>speak</em> fonksiyonu ile yakalanan data veri tabanındaki <em>Message</em> tablosuna
<code>ruby
Message.create! content: data['message']
</code> </p>
<p>ile kayıt edilir ve <em>Message</em> modelinde
<code>ruby
after_create_commit { MessageBroadcastJob.perform_later self }
</code>
ile job tetiklenir. Job çalıştığı anda <em>render_message</em> methodunu <em>‘room_channel’</em> kanalına </p>
<div class="highlight"><pre class="highlight ruby"><code> <span class="no">ActionCable</span><span class="p">.</span><span class="nf">server</span><span class="p">.</span><span class="nf">broadcast</span> <span class="s1">'room_channel'</span><span class="p">,</span> <span class="ss">message: </span><span class="n">render_message</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</code></pre></div>
<p>ile yayınlar. Yayınlanan data işlem yapılmak üzere <em>#app/assets/javascripts/channels/room.coffee</em> dosyasının içindeki <em>received</em> methoduna gider. Bu fonksiyon ile gelen data kullanıcı tarafına gönderilir.
Görüldüğü gibi Rails ile websocket işlemlerini yapmak ActionCable ile oldukça kolay. Son olarak bir dip not:</p>
<p>Eğer uygulamanızda Redis kullanıyorsanız cable.yml dosyamızdaki development ayarımızı şu şekilde
güncellememiz gerekiyor ve productionda ise Redis To Go URL'imizi vermeniz gerekmektedir: </p>
<div class="highlight"><pre class="highlight ruby"><code> <span class="ss">development:
adapter: </span><span class="n">redis</span>
<span class="ss">url: </span><span class="n">redis</span><span class="ss">:/</span><span class="o">/</span><span class="n">localhost</span><span class="p">:</span><span class="mi">6379</span><span class="o">/</span><span class="mi">1</span>
</code></pre></div>
Rails Verilerine Javascript Üzerinden Ulaşmak
http://lab2023.com/rails-verilerine-javascript-uzerinden-ulasmak.html
2017-02-03T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhaba,</p>
<p>Bu yazımda sizlere Gon gem'inin kullanımı ve Rails ile Javascript kullanırken GON sayesinde Rails tarafından oluşturulan
değişkenlerin Javascript tarafına nasıl aktarılacağını ve erişilebileceğini anlatmaya çalışacağım.</p>
<p>Javascript dosyasından HTML elementlerine herhangi bir veri içeriğini eklemek ve başka yerlerden erişmek için <code>data</code> özelliği kullanılır.
Data ile HTML elemanlarına veriler ekler ve bu verilere erişme imkanı bulabiliriz. </p>
<p>Basit bir örnek kullanımı aşağıdaki gibidir;</p>
<p>index.html.haml dosyasında:</p>
<div class="highlight"><pre class="highlight ruby"><code> <span class="n">content_tag</span> <span class="s2">"div"</span><span class="p">,</span> <span class="nb">id</span><span class="ss">:"products"</span><span class="p">,</span> <span class="ss">data: </span><span class="p">{</span> <span class="ss">url: </span><span class="n">products_url</span> <span class="p">}</span>
</code></pre></div>
<p>application.js.coffee dosyasında;</p>
<div class="highlight"><pre class="highlight plaintext"><code>jQuery->
console.log $(‘#products’).data(‘url’)
</code></pre></div>
<p>Bu şekilde kullandığımızda konsola data-url değerini basacaktır.</p>
<h1 id="gon-gem">Gon Gem</h1>
<p>Gon gem'i, Rails değişkenlerinize javascript dosyalarınızdan erişmenizi sağlayan bir gem'dir.</p>
<p>Javascript dosyanızda kullanmanız gereken bir veri olduğunda bunu view dosyalarından parse etmek yerine bu gem sayesinde
Rails verilerini kullanabileceğiniz işlerinizi kolaylaştıran bir araçtır.</p>
<h3 id="kullan-m">Kullanımı:</h3>
<p>Gemfile dosyasına;</p>
<div class="highlight"><pre class="highlight shell"><code> gem ‘gon’
</code></pre></div>
<p>app/views/layouts/application.html.haml dosyasına head tagleri arasına;</p>
<div class="highlight"><pre class="highlight shell"><code> <span class="o">=</span> Gon::Base.render_data
</code></pre></div>
<p>Controller.rb dosyasına;</p>
<div class="highlight"><pre class="highlight shell"><code> gon.your_variable <span class="o">=</span> variable_value
</code></pre></div>
<p>Javascript dosyasından;</p>
<div class="highlight"><pre class="highlight shell"><code> gon.your_variable
</code></pre></div>
<p>ile veriye erişebilirsiniz. İşte bu kadar.</p>
<p>Faydalı bir kullanımı da var. <code>gon.watch</code>ile sayfayı yenilemeden tutulan veriyi güncelleyebiliyorsunuz.</p>
<p><code>gon.watch</code> kullanımı ise şu şekildedir;</p>
<p>normalde gon.your_variable şeklinde oluşturduğunuz değişkeni; <code>gon.watch.your_variable</code> şeklinde oluşturuyorsunuz.</p>
<p>Daha sonra javascript dosyalarınızda aldığı bazı parametreler ile kullanabilirsiniz. Örneğin:
<code>gon.watch(name_of_variable, options, callback)</code> parametreleri ile kullanılabilmektedir.</p>
<div class="highlight"><pre class="highlight shell"><code>gon.watch<span class="o">(</span><span class="s1">'your_variable'</span>, interval: 1000, function_name<span class="o">)</span>
</code></pre></div>
<ul>
<li><strong>name_of_variable:</strong> controllerda tanımladığımız değişken</li>
<li><strong>options:</strong>
<ul>
<li><strong>interval:</strong> gon.watch için döngü oluşturmayı sağlar, döngü başarılı olduğunda callback çağrılır.</li>
<li><strong>method:</strong> ajax istekleri için method</li>
<li><strong>url:</strong> ajax istekleri için url </li>
</ul></li>
<li><strong>callback:</strong> ajax isteği başarılı olduğunda çağırılacak olan fonksiyondur.</li>
</ul>
<h1 id="rabl-gem">Rabl Gem</h1>
<p>Rabl, json cevapları için bir gem'dir. Açılımı Ruby API Builder Language şeklindedir. </p>
<p>JSON ise verinin hızlı ve küçük boyutlarda erişimini sağlar. Bilindiği üzere JSON, xml’in javascript ile uyumlu ve daha hızlı
kullanımını sağlayan bir alternatifidir.</p>
<h3 id="nas-l-kullan-l-r">Nasıl kullanılır?</h3>
<p>Gemfile dosyasına;</p>
<div class="highlight"><pre class="highlight shell"><code> gem ‘rabl’
</code></pre></div>
<p>eklenir.</p>
<p>JSON formatlı cevap dönmesini istediğimiz html sayfasının json.rabl uzantılı halini oluşturmalıyız. Örneğin index.html.haml sayfası için index.json.rabl dosyası oluşturmalıyız.
Örnek kullanımı aşağıdaki şekildedir;</p>
<p>index.json.rabl dosyasına:</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">object</span> <span class="vi">@products</span>
<span class="n">attributes</span> <span class="ss">:id</span><span class="p">,</span><span class="ss">:name</span><span class="p">,</span><span class="ss">:published_at</span>
<span class="k">if</span> <span class="n">current_user</span><span class="p">.</span><span class="nf">admin?</span>
<span class="n">node</span><span class="p">(</span><span class="ss">:edit_url</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">product</span><span class="o">|</span> <span class="n">edit_product_url</span><span class="p">(</span><span class="n">product</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre></div>
<p>Rabl dosyalarını html içine gömerek kaynak kodda görüntüleyebiliriz. Bunu için;</p>
<div class="highlight"><pre class="highlight haml"><code><span class="nf">#products</span><span class="p">{</span><span class="ss">data: </span><span class="p">{</span><span class="ss">articles: </span><span class="err">“</span> <span class="o">=</span> <span class="n">render</span> <span class="p">(</span><span class="ss">template: </span><span class="err">‘</span><span class="n">articles</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="nf">json</span><span class="p">.</span><span class="nf">rabl</span><span class="err">’</span><span class="p">)</span><span class="err">”</span><span class="p">}}</span>
</code></pre></div>
<p>kodunu ekleyelim.</p>
<h2 id="gon-geminin-rabl-le-kullan-m">Gon geminin Rabl İle Kullanımı</h2>
<p>Javascripte kullanmak istediğiniz veriyi rabl dosyasından çekebiliriz. Bunun için;</p>
<p>Index.json.rabl dosyası oluşturalım;</p>
<div class="highlight"><pre class="highlight ruby"><code> <span class="n">collection</span> <span class="no">Product</span><span class="p">.</span><span class="nf">limit</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="n">attributes</span> <span class="ss">:id</span><span class="p">,</span><span class="ss">:name</span><span class="p">,</span><span class="ss">:price</span>
</code></pre></div>
<p>Products_controller.rb dosyasında;</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">index</span>
<span class="n">gon</span><span class="p">.</span><span class="nf">rabl</span> <span class="err">“</span><span class="n">app</span><span class="o">/</span><span class="n">views</span><span class="o">/</span><span class="n">products</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="nf">json</span><span class="p">.</span><span class="nf">rabl</span><span class="err">”</span> <span class="p">,</span> <span class="ss">as: </span><span class="err">“</span><span class="n">products</span><span class="err">”</span>
<span class="k">end</span>
</code></pre></div>
<p>Application.js.coffee dosyasına;</p>
<div class="highlight"><pre class="highlight javascript"><code><span class="nx">gon</span><span class="p">.</span><span class="nx">products</span> <span class="k">if</span> <span class="nx">gon</span>
</code></pre></div>
<p>şeklinde kullanabiliriz.</p>
<p>Umarım bu yazım sizlere açıklayıcı ve ilgili araçların kullanımı ile ilgili fikir verici olmuştur.</p>
<p>İyi çalışmalar.</p>
Ruby on Rails Uygulamasının Heroku Servisinde Çoklu Ortamda (Staging, Production) Yayınlanması
http://lab2023.com/ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi.html
2016-08-04T03:00:00+03:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhaba,</p>
<p>Sizlere daha önceden rails uygulamanın yayına alınması yöntemlerinden biri olan kendi ubuntu sunucunuzda uygulamanın yayınlanması işlemini anlatmıştım. İlgili yazıya şu <a href="http://lab2023.com/ruby-on-rails-uygulamasinin-capistrano-3-ile-kolayca-yayinlanmasi.html">linkten</a> ulaşabilirsiniz.</p>
<p>Bu yazıda ise uygulamanın <a href="http://heroku.com" target="_blank">Heroku</a> servisi üzerinde, çoklu ortamlar(Staging, Production) için ayrı ayrı yayına alınması süreçlerinden ve her bir ortam için farklı git branch'lerinin kullanılması olayından bahsedeceğim.</p>
<p>Heroku üzerinde yayına alacağımız uygulamanın boş bir uygulama olması yerine bir kaç işlem yapabildiğimiz bir uygulama olması için <a href="https://github.com/lab2023/cybele/" target="_blank">Cybele</a> gem'ini kullanarak bir uygulama oluşturacağım. Kullandığım cybele versiyonu ise 1.9.2'dir.</p>
<p>Proje oluşturma adımı ile başlayacak olursak;</p>
<p>Terminalimizden cybele proje oluşturma komutunu çalıştırıyoruz;</p>
<div class="highlight"><pre class="highlight shell"><code> cybele blog
</code></pre></div>
<p>Daha sonrasında ise oluşturulan projemizin README.md dosyasında yeralan uygulama çalıştırılmadan önce yapılması gerekenleri yapıyoruz.
Bu işlemler ise;</p>
<ul>
<li>Proje dizininde yeralan .env.local değişkenlerini ayarlıyoruz.
Bu ayarlar içinde e-posta göndermek için kullandığımız SMTP ayarları olan aşağıda listelenen ayarlar bulunmaktadır.</li>
</ul>
<div class="highlight"><pre class="highlight ruby"><code> <span class="no">SMTP_PASSWORD</span><span class="o">=</span><span class="n">your_password</span>
<span class="no">SMTP_USER_NAME</span><span class="o">=</span><span class="n">your_user_name</span>
<span class="no">SMTP_ADDRESS</span><span class="o">=</span><span class="n">smtp</span><span class="p">.</span><span class="nf">sendgrid</span><span class="p">.</span><span class="nf">net</span>
</code></pre></div>
<p>Mail servisi olarak <a href="https://sendgrid.com" target="_blank">SendGrid</a> servisi size ücretsiz olarak aylık 12000 e-posta sağlamaktadır. Hobi projeleriniz için bu servisi kullanabilirsiniz. <a href="https://app.sendgrid.com/settings/credentials" target="_blank">Settings->Credentials</a> sayfasından gerekli username ve password'u alabilirsiniz.</p>
<ul>
<li>Hataları izleyebilmek için kullandığımız Rollbar servisinde aldığımız token'ı config/initializers/rollbar.rb dosyasında yer alan your_token yazan string ile değiştiriyoruz. Rollbar servisi üzerinde projenizi oluşturduğunuzda size doğrudan gerekli token'ı, yönergeleri ile birlikte verecektir.</li>
<li>User ve Admin model'leri için db/migrate/*.rb dizininde yeralan migration dosyalarındaki is_active alanının varsayılan değerini true olarak ayarlıyoruz.</li>
<li>Projenin config/settings.yml dosyasında yeralan username ve password alanlarını değiştiriyoruz.</li>
<li>Son olarakta projenin public dizini için VERSION.txt dosyası oluşturmak için şu komutu çalıştırıyoruz;</li>
</ul>
<div class="highlight"><pre class="highlight shell"><code> <span class="nb">ln</span> <span class="nt">-s</span> ../VERSION.txt VERSION.txt
</code></pre></div>
<p>Projemizde bu ayarları yaptıktan sonra, uygulamayı çalıştırma işlemlerine geçiyoruz. Bu adımda ise şu komutları sırasıyla çalıştırıyoruz.</p>
<div class="highlight"><pre class="highlight shell"><code> bundle
redis-server
rake sidekiq:start
rake db:create
rake db:migrate
rake dev:seed
rails server
</code></pre></div>
<p>Çalışan uygulamanın ekran görüntüsü aşağıdaki resimdeki gibi elde edilecektir.</p>
<p><a href="#"><img alt="cybele-ile-kurulmus-uygulama" src="assets/images/articles/2016-08-04-ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi/uygulama.png" /></a></p>
<p>Ayrıca localhost:3000/hq url'linden de uygulamanın yönetici bölümüne erişebilirsiniz. Yönetici giriş bilgileri db/seeds.rb dosyasında yer almaktadır.</p>
<p>Buraya kadar normal olarak projemizi oluşturmuş olduk. Şimdi çoklu ortamlarda kullanmak için git'in efektif bir dallanma eklentisi olan <a href="http://danielkummer.github.io/git-flow-cheatsheet/" target="_blank">git-flow</a> ile ilgili ayarlara.
Projemizin kök dizininde tanımlamış olduğumuz git yanına git-flow'u tanımlıyoruz. Git'in master branchinde iken şu komut ile git-flow'u aktif hale getiriyoruz.</p>
<div class="highlight"><pre class="highlight shell"><code> git flow init
</code></pre></div>
<p>Bu komut sayesinde release kodlarımızın yani production ortamı için kullanılacak kodlarımız master branch'inde, development kodlarımız yani staging sunucusunda yayınlayacağımız kodlar develop branch'inde tutulacaktır.
Git-flow tanımlama işleminin ardından artık heroku üzerinde uygulama oluşturma bölümüne geçiyoruz.
Heroku üzerinde heabımızı oluşturup giriş yaptıktan sonra yeni bir uygulama oluşturuyoruz.</p>
<p><a href="#"><img alt="heroku-uzerinde-uygulama-olusturma" src="assets/images/articles/2016-08-04-ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi/heroku-uygulama-olusturma.png" /></a></p>
<p>Oluşturduğumuz uygulamanın ismi eşsiz olmalıdır. Heroku size alt alanadı sağladığı için aynı isimli uygulamara izin vermemektedir.
Biz uygulama ismi olarak lab2023-blog-sample tercih ettik. Bu uygulama production ortamı için kullanacağımız kodları barındıracaktır.
Yukarıdaki adımları izleyerekten tekrar bir uygulama daha oluşturuyoruz. Bu uygulama ise staging ortamımız olacak ve develop branch'indeki kodlarımızı barındıracağız.
Staging ortamı için uygulama ismi olarak staging-lab2023-blog-sample'ı tercih ettik.</p>
<p>Production ve Staging uygulamalarımızı oluşturduktan sonra bu iki uygulamaya da uygulamanın detaylar sayfasında bulunan Resources sekmesinden Heroku Postgres::Database, Logentries ve Redis To Go elementlerini şekilde ki gibi ekliyoruz.</p>
<p><a href="#"><img alt="heroku-uzerinde-uygulamaya-element-ekleme" src="assets/images/articles/2016-08-04-ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi/heroku-uygulamaya-element-ekleme.png" /></a></p>
<p>Heroku Postgres::Database elementi PostgreSQL veritabanı için gereklidir.
Logentries elementi uygulama logları portal üzerinden analiz edebilmemiz için gereklidir.
Redis To Go elementi uygulama içinde kullandığımız Sidekiq arka plan işlerini gerçekleştirebilmemiz için gereklidir.</p>
<p>Uygulamamız için gerekli elementleri ekledikten sonra sıra geldi heroku uygulamalarımızın git ile ilgili ayarlarını yapma işlemine. Bu işlem için Production uygulamamız olan lab2023-blog-sample uygulamasının Detaylar sayfasından Settings sekmesine geliyoruz. Bu sayfada uygulama ile ilgili bir çok detayı bulabilirsiniz. Info bölümde yer alan Git URL alanındaki linki kopyalıyoruz.</p>
<p><a href="#"><img alt="heroku-uzerinde-uygulama-git-url" src="assets/images/articles/2016-08-04-ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi/heroku-uzerinde-uygulama-git-url.png" /></a></p>
<p>Bu kopyaladığımız git url'i terminalden proje dizinimize gelerek, aşağıdaki komutu kullanarak ekliyoruz.</p>
<div class="highlight"><pre class="highlight shell"><code> git remote add production https://git.heroku.com/lab2023-blog-sample.git
</code></pre></div>
<p>Git komutlarında kullancağınız remote.production.url'in ayarlandığını görmek için, şu komutu kullanabilirsiniz.</p>
<div class="highlight"><pre class="highlight shell"><code> git config <span class="nt">--list</span>
</code></pre></div>
<p>Eğer yanlış bir url eklemesi yaptıysanız şu komutu kullanarak eklediğiniz url'i kaldırabilirsiniz.</p>
<div class="highlight"><pre class="highlight shell"><code> git remote remove production
</code></pre></div>
<p>Bu uyguladığımız adımlardan terminalden url eklemeye kadar olan adımları aynı şekilde staging uygulaması olan staging-lab2023-blog-sample için de yapıyoruz.
Terminalden git url'i ekleme bölümünde ise şu şekilde ki komutu çalıştırıyoruz.</p>
<div class="highlight"><pre class="highlight shell"><code> git remote add staging https://git.heroku.com/staging-lab2023-blog-sample.git
</code></pre></div>
<p>Bu işlemlerden sonra artık uygulamamızın heroku urllerini de eklenmiş olduk.</p>
<p>Şimdi staging uygulamamıza kodları gönderme kısmına gelelim.
Bu işlemi yapabilmek için heroku uygulamalarına erişimimiz olması gerekmektedir. Heroku sunucularına, git ile uygulama kodlarını gönderebilmek için heroku komutları ile login olmalıyız. Heroku komutlarının kullanılabilmesi için ise <a href="https://toolbelt.heroku.com" target="_blank">Heroku Toolbelt</a> kurulumunu yapmalısınız.</p>
<p>Kurulum yapıldıktan sonra şu komut ile heroku hesabınıza giriş yapabilirsiniz;</p>
<div class="highlight"><pre class="highlight shell"><code> heroku login
</code></pre></div>
<p>Giriş yaptıktan sonra staging uygulamamızı yayına almak için şu komutu kullanıyoruz;</p>
<div class="highlight"><pre class="highlight shell"><code> git push staging develop:master
</code></pre></div>
<p>Bu komutta develop:master ile yapılmak istenen develop branch'indeki kodlar heroku üzerinde master branchine aktarılması işlemidir. Heroku uygulamaları master branch'te çalışmaktadır. Bu komutu çalıştırdıktan sonra uygulamamız artık heroku sunucusuna gönderilmiştir, şekilde gördüğünüz gibi.</p>
<p><a href="#"><img alt="heroku-uzerinde-uygulama-calismasi" src="assets/images/articles/2016-08-04-ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi/heroku-uzerinde-uygulama-calismasi.png" /></a></p>
<p>Proje dizinimizde bulunan Procfile sayesinde bir web bir de worker dynosu çalıştırılabilir duruma gelmiştir. Web dynosu varsayılan olarak direk çalıştırılmıştır. Worker'ı ise uygulama detay sayfasında Resources sekmesinde bulunan sayfadan açmamız gerekmektedir. Worker'ı da çalıştırdıktan sonra uygulamamızın son hali şekildeki gibidir.</p>
<p><a href="#"><img alt="heroku-uzerinde-uygulama-calismasi-2" src="assets/images/articles/2016-08-04-ruby-on-rails-uygulamasinin-heroku-servisinde-coklu-ortamda-yayinlanmasi/heroku-uzerinde-uygulama-calismasi-2.png" /></a></p>
<p>Worker'larımızın sidekiq ayarları config/sidekiq.yml dosyasında bulunmaktadır. Burada production ortamı için concurrency: 25 olarak ayarlanmıştır. Redis To Go ücretsiz paketi düşük özelliklere sahip olduğu için 25 thread'e izin vermemektedir. Bunu 3 olarak ayarlarsak production ortamı içinde problem yaşamadan uygulamamızı yayınlamış oluruz.</p>
<p>Uygulamamızı sunucuya gönderdik ve web ile worker dynolarını çalışır hale getirdik. Şimdi heroku üzerinde veritabanı için migration dosyalarını koşma ve seed rake'lerini çalıştırma işlemine geçiyoruz.</p>
<div class="highlight"><pre class="highlight shell"><code> heroku run rake db:migrate <span class="nt">--app</span> staging-lab2023-blog-sample
heroku run rake dev:seed <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Heroku uygulamasında rails console'a erişmek için gerekli komut;</p>
<div class="highlight"><pre class="highlight shell"><code> heroku run rake console <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Bu işlemlerden sonra .env.local dosyamızda tutduğumuz ENV değişkenlerinin heroku üzerinde ayarlanması işlemine geçeçek olursak, şu komut ile bu değişkenleri ayarlayabiliriz.</p>
<div class="highlight"><pre class="highlight shell"><code> heroku config:set <span class="nv">SMTP_ADDRESS</span><span class="o">=</span>smtp.sendgrid.net <span class="nt">--app</span> staging-lab2023-blog-sample
heroku config:set <span class="nv">SSMTP_USER_NAME</span><span class="o">=</span>your_user_name <span class="nt">--app</span> staging-lab2023-blog-sample
heroku config:set <span class="nv">SMTP_PASSWORD</span><span class="o">=</span>your_password <span class="nt">--app</span> staging-lab2023-blog-sample
heroku config:set <span class="nv">ROOT_PATH</span><span class="o">=</span>https://staging-lab2023-blog-sample.herokuapp.com <span class="nt">--app</span> staging-lab2023-blog-sample
heroku config:set <span class="nv">BASIC_AUTH_IS_ACTIVE</span><span class="o">=</span><span class="nb">yes</span> <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Ayarlarınızı bu komutlar ile ayarladıktan sonra heroku üzerinde uygulamanın ayarlar sayfasında Config Variables bölümünde bu değişkenleri görebilirsiniz, ayrıca portal üzerinden de bu değişkenleri değiştirebilirsiniz. Herokuya rails uygulaması gönderildiğinde RAILS_ENV varsayılan olarak production olarak ayarlanıyor. RAILS_ENV değerini de staging ile değiştirebilirsiniz.</p>
<div class="highlight"><pre class="highlight shell"><code> heroku config:set <span class="nv">RAILS_ENV</span><span class="o">=</span>staging <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Şu komut ile de heroku üzerindeki değişkenlerinizi listeleyebilirsiniz;</p>
<div class="highlight"><pre class="highlight shell"><code> heroku config <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Şu komut ile çalışan dynolarınızı listeleyebilirsiniz;</p>
<div class="highlight"><pre class="highlight shell"><code> heroku ps <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Şu komut ile dynolarınızı(web, worker) yeniden başlatabilirsiniz;</p>
<div class="highlight"><pre class="highlight shell"><code> heroku ps:restart <span class="nt">--app</span> staging-lab2023-blog-sample
</code></pre></div>
<p>Komut bilgilerinin ardından production ortamında uygulamamızı yayınlama işlemine gelecek olursak; Şu anda master branch'imizde herhangi bir release kodu bulunmamakta. Git-flow'dan yararlanarak v1.0.0 etiketi ile bir versiyon yayınlayalım.
Bu işlem için gerekli olan komutlar şunlardır;</p>
<div class="highlight"><pre class="highlight shell"><code> git flow release start v1.0.0
git flow release finish v1.0.0
</code></pre></div>
<p>Git-flow sayesinde çıkardığımız ilk release'i lab2023-blog-sample heroku uygulamamıza göndermek için gerekli komut;</p>
<div class="highlight"><pre class="highlight shell"><code> git push production master
</code></pre></div>
<p>Uygulamamızı production ortamına gönderdik sonra aynı staging ortamında olduğu gibi diğer komutları uygulamaya özel olarak çalıştırıyoruz.</p>
<div class="highlight"><pre class="highlight shell"><code> heroku run rake db:migrate <span class="nt">--app</span> lab2023-blog-sample
heroku run rake dev:seed <span class="nt">--app</span> lab2023-blog-sample
heroku config:set <span class="nv">SMTP_ADDRESS</span><span class="o">=</span>smtp.sendgrid.net <span class="nt">--app</span> lab2023-blog-sample
heroku config:set <span class="nv">SSMTP_USER_NAME</span><span class="o">=</span>your_user_name <span class="nt">--app</span> lab2023-blog-sample
heroku config:set <span class="nv">SMTP_PASSWORD</span><span class="o">=</span>your_password <span class="nt">--app</span> lab2023-blog-sample
heroku config:set <span class="nv">ROOT_PATH</span><span class="o">=</span>https://lab2023-blog-sample.herokuapp.com <span class="nt">--app</span> lab2023-blog-sample
heroku config:set <span class="nv">BASIC_AUTH_IS_ACTIVE</span><span class="o">=</span>no <span class="nt">--app</span> lab2023-blog-sample
<span class="c"># Tek seferde bütün ayarları yapmak isterseniz şu komutu kullanabilirsiniz</span>
heroku config:set <span class="nv">SMTP_ADDRESS</span><span class="o">=</span>smtp.sendgrid.net <span class="nv">SSMTP_USER_NAME</span><span class="o">=</span>your_user_name <span class="nv">SMTP_PASSWORD</span><span class="o">=</span>your_password <span class="nv">ROOT_PATH</span><span class="o">=</span>https://lab2023-blog-sample.herokuapp.com <span class="nv">BASIC_AUTH_IS_ACTIVE</span><span class="o">=</span>no <span class="nt">--app</span> lab2023-blog-sample
</code></pre></div>
<p>Uygulamamız da ilk kez bu komutları çalıştırdıktan sonra yeni değişiklikleri sunucuya göndermek için kullanacağımız komutlar;</p>
<p>Staging ortamı için;</p>
<div class="highlight"><pre class="highlight shell"><code> git push staging develop:master
</code></pre></div>
<p>Production ortamı için;</p>
<div class="highlight"><pre class="highlight shell"><code> git push production master
</code></pre></div>
<p>Eğer yeni migration dosyalarınız veya çalıştırmanız gereken özel rake'ler varsa yukarıdaki komutlardaki gibi uygulamayı belirterek çalıştırmanız yeterlidir.</p>
<p>Gemfile dosyanızda özel github repolarınız varsa bu repolara heroku uygulamanızın erişebilmesi için herokuya özel oluştruduğunuz ssh keylerinizi şu komut ile herokuya ekleyebilirsiniz;</p>
<div class="highlight"><pre class="highlight shell"><code> heroku keys:add ~/.ssh/heroku_id_rsa.pub
</code></pre></div>
<p>Sık ihtiyac duyabileceğiniz bazı komutların listesi aşağıdaki gibidir;</p>
<div class="highlight"><pre class="highlight shell"><code> <span class="c"># Web dynonusunu yeniden başlatır</span>
heroku ps:restart web
<span class="c"># Worker dynonusunu yeniden başlatır</span>
heroku restart worker
<span class="c"># Yapılması gereken ağır işleri farklı dyno büyüklüklerinde çalıştırmak isterseniz</span>
heroku run <span class="nt">--size</span><span class="o">=</span>standard-2x rake heavy:job
heroku run <span class="nt">--size</span><span class="o">=</span>performance-l rake heavy:job
<span class="c"># Uygulama loglarını terminalden izleyebilmeniz için</span>
heroku logs
heroku logs <span class="nt">--tail</span>
heroku logs <span class="nt">--source</span> app <span class="nt">--tail</span>
<span class="c"># Uygulamanın veritabanı bilgilerini listelemek isterseniz</span>
heroku pg
<span class="c"># Uygulamanın veritabanı yedek alma zaman planı</span>
heroku pg:backups schedules
<span class="c"># Uygulamanın veritabanın düzenli olarak yedek almasını istiyorsanız</span>
heroku pg:backups schedule <span class="nt">--at</span> <span class="s1">'04:00 Europe/Istanbul'</span>
</code></pre></div>
<p>Örnek uygulamaya şu <a href="https://lab2023-blog-sample.herokuapp.com/" target="_blank">linkten</a> ulaşabilirsiniz.
Örnek kaynak kodlar ise şu <a href="https://github.com/ismailakbudak/lab2023-blog-sample" target="_blank">linkten</a> ulaşabilirsiniz.</p>
<p>Umarım faydalı bir yazı olmuştur.
İyi çalışmalar..</p>
Bulutfon Ruby SDK
http://lab2023.com/bulutfon-ruby-sdk.html
2015-12-22T02:00:00+02:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhaba,</p>
<p>Bugün sizlere, gelişiminde bizim de katkıda bulunduğumuz
<a href="https://www.bulutfon.com/?ref=1"><code>Bulutfon API</code></a> ‘si için <code>Ruby</code> programlama dili ile yazılmış olan <a href="https://github.com/bulutfon/ruby-sdk"><code>bulutfon_sdk gem</code></a> 'den bahsedecek ve örnek kodlar göstereceğiz.</p>
<p>Bu gem ile uygulamanızın <a href="https://github.com/bulutfon/documents"><code>Bulutfon API Servisi</code></a> ile kolayca haberleşmesini sağlayabileceksiniz. SMS gönderme, arama kayıtlarına erişme, otomatik arama
oluşturma gibi birçok özelliği hızlı bir şekilde uygulamalarınıza entegre edebileceksiniz. <a href="http://api.bulutfon.com/docs"><code>Bulutfon API</code></a> ile daha fazla neler yapabileceğiniz hakkında bilgi almak için
<a href="https://github.com/bulutfon/documents">https://github.com/bulutfon/documents</a> adresine göz atabilirsiniz.</p>
<p>Sözü daha fazla uzatmadan örnek kodlara geçelim;</p>
<h1 id="bulutfon_sdk-gem-inin-y-kl-oldu-undan-emin-oluyoruz">bulutfon_sdk gem 'inin yüklü olduğundan emin oluyoruz.</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">require</span> <span class="s1">'bulutfon_sdk'</span>
</code></pre></div>
<h1 id="bulutfon-hesab-n-zdan-alman-z-gereken-api-master-token">Bulutfon hesabınızdan almanız gereken API master token</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">token</span> <span class="o">=</span> <span class="s1">'your_token'</span>
</code></pre></div>
<h1 id="hesap-ile-ilgili-i-lemler">Hesap ile ilgili işlemler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">bulutfon</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Bulutfon</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="hesap-detaylar">Hesap detayları</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">details</span>
</code></pre></div>
<h1 id="bulutfon-zerinden-eri-ebilece-iniz-nesneler-ayr-ca-bu-nesneleri-ayr-ayr-kullanmak-isterseniz-alt-b-l-mlerdeki-kodlar-inceleyeniz">Bulutfon üzerinden erişebileceğiniz nesneler. Ayrıca bu nesneleri ayrı ayrı kullanmak isterseniz alt bölümlerdeki kodları inceleyeniz.</h1>
<h1 id="rne-in-sms-g-ndermek-i-in-bulutfonsdk-rest-message-s-n-f-n-yaln-z-ba-na-kullanabilirsiniz-alt-k-s-mda-rne-i-bulunmaktad-r">Örneğin SMS göndermek için <code>BulutfonSDK::REST::Message</code> sınıfını yalnız başına kullanabilirsiniz. Alt kısımda örneği bulunmaktadır.</h1>
<h1 id="bulutfonsdk-rest-message-objesi">BulutfonSDK::REST::Message objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">messages</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-messagetitle-objesi">BulutfonSDK::REST::MessageTitle objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">message_titles</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-did-objesi">BulutfonSDK::REST::Did objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">dids</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-extension-objesi">BulutfonSDK::REST::Extension objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">extensions</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-group-objesi">BulutfonSDK::REST::Group objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">groups</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-cdr-objesi">BulutfonSDK::REST::Cdr objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">cdrs</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-callrecord-objesi">BulutfonSDK::REST::CallRecord objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">call_records</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-incomingfax-objesi">BulutfonSDK::REST::IncomingFax objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">incoming_faxes</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-outgoingfax-objesi">BulutfonSDK::REST::OutgoingFax objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">outgoing_faxes</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-announcement-objesi">BulutfonSDK::REST::Announcement objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">announcements</span>
</code></pre></div>
<h1 id="bulutfonsdk-rest-automaticcall-objesi">BulutfonSDK::REST::AutomaticCall objesi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">bulutfon</span><span class="p">.</span><span class="nf">automatic_calls</span>
</code></pre></div>
<h1 id="santrale-ba-l-telefon-numaralar">Santrale bağlı telefon numaraları</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">did</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Did</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="santrale-ba-l-telefon-numaralar-n-listeler">Santrale bağlı telefon numaralarını listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">did</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="id-si-verilen-santral-numaras-n-n-detaylar-n-getirir">Id 'si verilen santral numarasının detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">did</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="dahililer">Dahililer</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">extension</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Extension</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="dahililerin-hepsini-getirir">Dahililerin hepsini getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">extension</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="id-si-verilen-dahili-detaylar-n-getirir">Id 'si verilen dahili detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">extension</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="yeni-bir-dahili-olu-turma-i-lemi">Yeni bir dahili oluşturma işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">full_name: </span><span class="s1">'Deneme'</span><span class="p">,</span>
<span class="ss">email: </span><span class="s1">'deneme@deneme.com'</span><span class="p">,</span>
<span class="ss">did: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">number: </span><span class="mi">9999</span><span class="p">,</span>
<span class="ss">redirection_type: </span><span class="s1">'NONE'</span><span class="p">,</span>
<span class="ss">destination_type: </span><span class="s1">'EXTENSION'</span><span class="p">,</span>
<span class="ss">destination_number: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="s1">'acl[]'</span> <span class="o">=></span> <span class="p">[</span> <span class="s1">'domestic'</span><span class="p">,</span> <span class="s1">'gsm'</span><span class="p">,</span> <span class="s1">'international'</span><span class="p">]</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">extension</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="dahili-g-ncelleme-i-lemi">Dahili güncelleme işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">full_name: </span><span class="s1">'Deneme Deneme'</span><span class="p">,</span>
<span class="s1">'acl[]'</span> <span class="o">=></span> <span class="p">[</span> <span class="s1">'domestic'</span><span class="p">,</span> <span class="s1">'gsm'</span><span class="p">]</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">extension</span><span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="dahili-silme-i-lemi">Dahili silme işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">extension</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="gruplar">Gruplar</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">group</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Group</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="gruplar-listeler">Grupları listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">group</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="id-si-verilen-grup-detaylar-n-getirir">Id 'si verilen grup detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">group</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="arama-kay-tlar">Arama kayıtları</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">cdr</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Cdr</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="t-m-arama-kay-tlar-n-listeler">Tüm arama kayıtlarını listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">cdr</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="arama-kay-tlar-n-sayfalama-yaparak-getirir">Arama kayıtlarını sayfalama yaparak getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">cdr</span><span class="p">.</span><span class="nf">all</span><span class="p">({</span><span class="ss">page: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">limit: </span><span class="mi">1</span><span class="p">})</span>
</code></pre></div>
<h1 id="uuid-si-verilen-arama-kayd-detaylar-n-getirir">Uuid 'si verilen arama kaydı detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">cdr</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="s1">'uuid'</span><span class="p">)</span>
</code></pre></div>
<h1 id="ses-kay-tlar">Ses kayıtları</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">call_record</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">CallRecord</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="uuid-si-verilen-ses-kayd-n-n-bilgilerini-getirir">Uuid 'si verilen ses kaydının bilgilerini getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">call_record</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="s1">'uuid'</span><span class="p">)</span>
</code></pre></div>
<h1 id="uuid-si-verilen-ses-kayd-n-verilen-save_path-dosyas-na-kay-t-eder">Uuid 'si verilen ses kaydını verilen save_path dosyasına kayıt eder</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">save_path</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/save_uuid.ogg"</span>
<span class="nb">puts</span> <span class="n">call_record</span><span class="p">.</span><span class="nf">save</span><span class="p">(</span><span class="s1">'uuid'</span><span class="p">,</span> <span class="n">save_path</span><span class="p">)</span>
</code></pre></div>
<h1 id="gelen-fakslar">Gelen fakslar</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">incoming_fax</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">IncomingFax</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="gelen-fakslar-listeler">Gelen faksları listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">incoming_fax</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="uuid-si-verilen-gelen-faks-detaylar-n-getirir">Uuid 'si verilen gelen faks detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">incoming_fax</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="s1">'uuid'</span><span class="p">)</span>
</code></pre></div>
<h1 id="uuid-si-verilen-gelen-faks-dosyas-n-save_path-dosyas-n-kay-t-eder">Uuid 'si verilen gelen faks dosyasını save_path dosyasını kayıt eder</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">save_path</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/save_uuid.tiff"</span>
<span class="nb">puts</span> <span class="n">incoming_fax</span><span class="p">.</span><span class="nf">save</span><span class="p">(</span><span class="s1">'uuid'</span><span class="p">,</span> <span class="n">save_path</span><span class="p">)</span>
</code></pre></div>
<h1 id="giden-fakslar">Giden fakslar</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">outgoing_fax</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">OutgoingFax</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="giden-fakslar-listeler">Giden faksları listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">outgoing_fax</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="id-si-verilen-giden-faks-detaylar-n-getirir">Id 'si verilen giden faks detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">outgoing_fax</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="giden-faks-olu-turma-i-lemi">Giden faks oluşturma işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">file</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/pdf-sample.pdf"</span>
<span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">title: </span><span class="s1">'Deneme'</span><span class="p">,</span>
<span class="ss">receivers: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">did: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">attachment: </span><span class="n">file</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">outgoing_fax</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="ses-dosyalar">Ses Dosyaları</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">announcement</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Announcement</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="ses-dosyalar-n-listeler">Ses dosyalarını listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">announcement</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="id-si-verilen-ses-dosyas-detaylar-n-getirir">Id 'si verilen ses dosyası detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">announcement</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="ses-dosyas-olu-turur">Ses dosyası oluşturur</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">file</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/test.wav"</span>
<span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">name: </span><span class="s1">'Deneme'</span><span class="p">,</span>
<span class="ss">announcement: </span><span class="n">file</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">announcement</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="id-si-verilen-ses-dosyas-n-veilen-dosya-yoluna-kay-t-eder">Id 'si verilen ses dosyasını, veilen dosya yoluna kayıt eder</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">save_path</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/save_test.wav"</span>
<span class="nb">puts</span> <span class="n">announcement</span><span class="p">.</span><span class="nf">save</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">save_path</span><span class="p">)</span>
</code></pre></div>
<h1 id="id-si-verilen-ses-dosyas-n-siler">Id 'si verilen ses dosyasını siler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">announcement</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="otomatik-aramalar">Otomatik Aramalar</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">automatic_call</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">AutomaticCall</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="otomatik-aramalar-listesini-getirir">Otomatik aramalar listesini getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">automatic_call</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="id-si-verilen-otomatik-arama-detaylar-n-geitirir">Id 'si verilen otomatik arama detaylarını geitirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">automatic_call</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="otomatik-arama-olu-turur-ve-olu-turma-i-leminden-sonra-receivers-numaralar-aran-r">Otomatik arama oluşturur ve oluşturma işleminden sonra receivers numaraları aranır.</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">title: </span><span class="s1">'Automatic call after creation'</span><span class="p">,</span>
<span class="ss">receivers: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">did: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">announcement_id: </span><span class="mi">1</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">automatic_call</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="zaman-planl-otomatik-arama-olu-turulur-bu-parametrelerde-receivers-numaralar-per-embe-g-n-10-15-ve-12-00-saatleri-aras-nda-aran-r">Zaman planlı otomatik arama oluşturulur, Bu parametrelerde, receivers numaraları perşembe günü 10:15 ve 12:00 saatleri arasında aranır.</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">title: </span><span class="s1">'Time planned call'</span><span class="p">,</span>
<span class="ss">receivers: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">did: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">announcement_id: </span><span class="mi">1</span><span class="p">,</span>
<span class="ss">mon_active: </span><span class="kp">false</span><span class="p">,</span>
<span class="ss">tue_active: </span><span class="kp">false</span><span class="p">,</span>
<span class="ss">wed_active: </span><span class="kp">false</span><span class="p">,</span>
<span class="ss">thu_active: </span><span class="kp">true</span><span class="p">,</span>
<span class="ss">thu_start: </span><span class="s1">'10:15'</span><span class="p">,</span>
<span class="ss">thu_finish: </span><span class="s1">'12:00'</span><span class="p">,</span>
<span class="ss">fri_active: </span><span class="kp">false</span><span class="p">,</span>
<span class="ss">sat_active: </span><span class="kp">false</span><span class="p">,</span>
<span class="ss">sun_active: </span><span class="kp">false</span><span class="p">,</span>
<span class="ss">hours_active: </span><span class="kp">true</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">automatic_call</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="mesaj-ba-l-klar">Mesaj Başlıkları</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">message_title</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">MessageTitle</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="mesaj-ba-l-klar-n-listeler">Mesaj başlıklarını listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">message_title</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="mesajlar">Mesajlar</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">message</span> <span class="o">=</span> <span class="no">BulutfonSDK</span><span class="o">::</span><span class="no">REST</span><span class="o">::</span><span class="no">Message</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
</code></pre></div>
<h1 id="mesajlar-listeler">Mesajları listeler</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">message</span><span class="p">.</span><span class="nf">all</span>
</code></pre></div>
<h1 id="mesajlar-sayfalama-yap-larak-listelenir">Mesajları sayfalama yapılarak listelenir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">message</span><span class="p">.</span><span class="nf">all</span><span class="p">({</span><span class="ss">page: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">limit: </span><span class="mi">3</span> <span class="p">})</span>
</code></pre></div>
<h1 id="id-si-verilen-mesaj-detaylar-n-getirir">Id 'si verilen mesaj detaylarını getirir</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="nb">puts</span> <span class="n">message</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h1 id="sms-mesaj-olu-turma-i-lemi">SMS mesajı oluşturma işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">title: </span><span class="s1">'CONFIRMED_MESSAGE_TITLE'</span><span class="p">,</span>
<span class="ss">content: </span><span class="s1">'Test Message'</span><span class="p">,</span>
<span class="ss">receivers: </span><span class="s1">'905xxxxxxxxx'</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">message</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<h1 id="ok-al-c-l-mesja-g-nderme-i-lemi">Çok alıcılı mesja gönderme işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params_multiple</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">title: </span><span class="s1">'CONFIRMED_MESSAGE_TITLE'</span><span class="p">,</span>
<span class="ss">content: </span><span class="s1">'Multiple Message'</span><span class="p">,</span>
<span class="ss">receivers: </span><span class="s1">'905xxxxxxxxx,905xxxxxxxxx'</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">message</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params_multiple</span><span class="p">)</span>
</code></pre></div>
<h1 id="zaman-planl-mesaj-g-nderme-i-lemi">Zaman planlı mesaj gönderme işlemi</h1>
<div class="highlight"><pre class="highlight ruby"><code><span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">title: </span><span class="s1">'CONFIRMED_MESSAGE_TITLE'</span><span class="p">,</span>
<span class="ss">content: </span><span class="s1">'Planned message example'</span><span class="p">,</span>
<span class="ss">receivers: </span><span class="s1">'905xxxxxxxxx'</span><span class="p">,</span>
<span class="ss">is_future_sms: </span><span class="kp">true</span><span class="p">,</span>
<span class="ss">send_date: </span><span class="s1">'16/12/2015 10:00'</span>
<span class="p">}</span>
<span class="nb">puts</span> <span class="n">message</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</code></pre></div>
<p>Kaynakça,</p>
<ul>
<li><a href="https://www.bulutfon.com/?ref=1">https://bulutfon.com/</a></li>
<li><a href="https://github.com/bulutfon/documents">https://github.com/bulutfon/documents</a></li>
<li><a href="https://github.com/bulutfon/ruby-sdk">https://github.com/bulutfon/ruby-sdk</a></li>
<li><a href="http://api.bulutfon.com/docs">http://api.bulutfon.com/docs</a></li>
<li><a href="http://devforums.bulutfon.com/">http://devforums.bulutfon.com/</a></li>
</ul>
Deploy Ruby on Rails Application Quickly With Capistrano 3
http://lab2023.com/deploy-ruby-on-rails-application-quickly-with-capistrano.html
2015-12-21T02:00:00+02:00
2023-11-02T16:54:44+03:00
lab2023
<p>Hi,</p>
<p>In this post, We will write about the <a href="https://github.com/capistrano/capistrano" target="_blank">Capistrano</a> deploy tool on <code>Ruby On Rails(ROR)</code> and We will share some code blocks
that is a bash script for starting the server from beginning. We are using Ubuntu-14.04 server. Capistrano version is 3.4. Ruby version on our server is 2.2.3. Capistrano is an open source project,
if you want to look the source code, you can visit the <a href="https://github.com/capistrano/capistrano" target="_blank">github</a> page.
<<<<<<< HEAD</p>
<h1 id="for-example-you-can-use-netinternet-or-digitalocean-server-suppliers-you-can-prepare-your-server-within-2-3-hours-with-the-following-bash-scripts">For example you can use <a href="https://www.netinternet.com.tr/ssd-vds-sunucular">Netinternet</a> or <a href="https://www.digitalocean.com/">DigitalOcean</a> server suppliers. You can prepare your server within 2-3 hours w<span id="result_box" class="short_text" lang="en"><span class="hps">ith</span> <span class="hps">the following bash</span> <span class="hps">scripts.</h1>
<p>For example you can use <a href="http://www.netinternet.com.tr/panel/aff.php?aff=916">Netinternet</a> or <a href="https://www.digitalocean.com/">DigitalOcean</a> server suppliers. You can prepare your server within 2-3 hours w<span id="result_box" class="short_text" lang="en"><span class="hps">ith</span> <span class="hps">the following bash</span> <span class="hps">scripts.</p>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>hotfix/v1.11.2.0
Those bash scripts prepare basic environment for Ruby libraries and create <code>deploy user</code> for using on deployment process. Also one of them prepares Ruby environment under the <code>deploy user</code> home folder(default <code>deploy user</code> name you can change it before to run scripts)</span></span> .</p>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
<p>Base installation bash script for Ruby environment is as follows. You must run this script as a root user.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="c">## Run this script with root user</span>
<span class="c">## Fancy echo</span>
fancy_echo<span class="o">()</span> <span class="o">{</span>
<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">%b</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
<span class="o">}</span>
fancy_echo <span class="s2">"Updating system packages ..."</span>
apt-get <span class="nt">-y</span> update
apt-get <span class="nt">-y</span> upgrade
fancy_echo <span class="s2">"Installing python-software-properties..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>python-software-properties
fancy_echo <span class="s2">"Installing software-properties-common..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>software-properties-common
fancy_echo <span class="s2">"Exporting language"</span>
<span class="nb">export </span><span class="nv">LANGUAGE</span><span class="o">=</span>en_US.UTF-8 <span class="o">&&</span> <span class="nb">export </span><span class="nv">LANG</span><span class="o">=</span>en_US.UTF-8 <span class="o">&&</span> <span class="nb">export </span><span class="nv">LC_ALL</span><span class="o">=</span>en_US.UTF-8 <span class="o">&&</span> locale-gen en_US.UTF-8 <span class="o">&&</span> dpkg-reconfigure locales
fancy_echo <span class="s2">"Installing libraries for common gem dependencies ..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
apt-get <span class="nb">install </span>git-core openssl curl libreadline-dev libxslt1-dev libcurl4-openssl-dev ruby-dev make make-doc
fancy_echo <span class="s2">"Installing nodejs ..."</span>
add-apt-repository <span class="nt">-y</span> ppa:chris-lea/node.js
apt-get <span class="nt">-y</span> update
apt-get <span class="nt">-y</span> <span class="nb">install </span>nodejs
apt-get <span class="nt">-y</span> <span class="nb">install </span>libxslt-dev libxml2-dev
fancy_echo <span class="s2">"Installing imagemagick ..."</span>
apt-get <span class="nb">install</span> <span class="nt">-y</span> imagemagick
fancy_echo <span class="s2">"Installing nginx ..."</span>
add-apt-repository <span class="nt">-y</span> ppa:nginx/stable
apt-get <span class="nt">-y</span> update
apt-get <span class="nt">-y</span> <span class="nb">install </span>nginx
service nginx start
fancy_echo <span class="s2">"Installing postgresql ..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>postgresql libpq-dev
</code></pre></div>
<p>Deploy user creating script is as follows. You must run this script as a root user too.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="c"># Deploy group</span>
<span class="nv">deploy_group</span><span class="o">=</span>deploy
<span class="c"># Deploy user</span>
<span class="nv">deploy_user</span><span class="o">=</span>deploy
<span class="c"># Github usernames for access with ssh to deploy user</span>
<span class="nv">usernames</span><span class="o">=(</span>tayfunoziserikan ismailakbudak<span class="o">)</span>
<span class="c"># Check user is exist</span>
<span class="nb">id</span> <span class="nt">-u</span> <span class="nv">$deploy_user</span> &> /dev/null
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span>
<span class="k">then
</span><span class="nb">echo</span> <span class="s2">"* Add </span><span class="nv">$deploy_group</span><span class="s2"> group"</span>
groupadd <span class="nv">$deploy_group</span>
<span class="nb">echo</span> <span class="s2">"* Creating user </span><span class="nv">$deploy_user</span><span class="s2">"</span>
useradd <span class="nt">-m</span> <span class="nt">-g</span> <span class="nv">$deploy_group</span> <span class="nt">-s</span> /bin/bash <span class="nv">$deploy_user</span>
<span class="nb">echo</span> <span class="s2">"* Adding user </span><span class="nv">$deploy_user</span><span class="s2"> to sudoers"</span>
<span class="nb">chmod</span> +w /etc/sudoers
<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$deploy_user</span><span class="s2"> ALL=(ALL) ALL"</span> <span class="o">>></span> /etc/sudoers
<span class="nb">chmod</span> <span class="nt">-w</span> /etc/sudoers
<span class="k">else
</span><span class="nb">echo</span> <span class="s2">"* </span><span class="nv">$deploy_user</span><span class="s2"> user already exists"</span>
<span class="k">fi</span>
<span class="c"># Check user is exist, maybe some errors occured</span>
<span class="nb">id</span> <span class="nt">-u</span> <span class="nv">$deploy_user</span> &> /dev/null
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span>
<span class="k">then
</span><span class="nb">echo</span> <span class="s2">"* </span><span class="nv">$deploy_user</span><span class="s2"> user does not exists"</span>
<span class="k">else</span>
<span class="c"># Prepare ssh keys environment</span>
<span class="nb">echo</span> <span class="s2">"* Add .ssh directory to </span><span class="nv">$deploy_user</span><span class="s2">"</span>
<span class="nb">test</span> <span class="nt">-d</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span>
<span class="k">then
</span><span class="nb">mkdir</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="c"># change user permisisions</span>
<span class="c"># 700 => (owner read/write/execute, group none, other none)</span>
<span class="nb">chmod </span>700 /home/<span class="nv">$deploy_user</span>/.ssh
<span class="nb">chown</span> <span class="nv">$deploy_user</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="nb">chgrp</span> <span class="nv">$deploy_group</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="k">fi
</span><span class="nb">echo</span> <span class="s2">"* Get usernames public keys from GitHub and add them to </span><span class="nv">$deploy_user</span><span class="s2"> authorized_keys"</span>
<span class="k">for </span>username <span class="k">in</span> <span class="k">${</span><span class="nv">usernames</span><span class="p">[@]</span><span class="k">}</span><span class="p">;</span> <span class="k">do
</span><span class="nv">name</span><span class="o">=</span><span class="nv">$username</span>.keys
wget https://github.com/<span class="nv">$name</span> <span class="nt">--no-check-certificate</span> <span class="nt">-O</span> <span class="nv">$name</span>
<span class="nb">cat</span> <span class="nv">$name</span> <span class="o">>></span> /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">rm</span> <span class="nv">$name</span> <span class="c"># remove temprory file</span>
<span class="k">done</span>
<span class="c"># change user permisisions</span>
<span class="c"># 600 => (owner read/write, group none, other none)</span>
<span class="nb">chmod </span>600 /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">chown</span> <span class="nv">$deploy_user</span> /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">chgrp</span> <span class="nv">$deploy_group</span> /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">echo</span> <span class="s2">"* Completed..."</span>
<span class="k">fi</span>
</code></pre></div>
<p> </p>
<p>This script is preparing ruby environment for <code>deploy user</code>. You should run this script as a <code>deploy user</code>.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="c">## Run this command with deploy user</span>
<span class="c"># define user home path</span>
<span class="nv">user_path</span><span class="o">=</span>/home/deploy
<span class="c">## Fancy echo</span>
fancy_echo<span class="o">()</span> <span class="o">{</span>
<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">%b</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
<span class="o">}</span>
fancy_echo <span class="s2">"Installing rbenv..."</span>
git clone git://github.com/sstephenson/rbenv.git <span class="nv">$user_path</span>/.rbenv
fancy_echo <span class="s2">"Writing rbenv path to bashrc ..."</span>
<span class="nb">echo</span> <span class="s1">'export PATH=\"$HOME/.rbenv/bin:$PATH\"'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
<span class="nb">echo</span> <span class="s1">'eval "$(rbenv init -)"'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
fancy_echo <span class="s2">"Exporting rbenv path..."</span>
<span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.rbenv/bin:</span><span class="nv">$PATH</span><span class="s2">"</span>
<span class="nb">eval</span> <span class="s2">"</span><span class="si">$(</span>rbenv init -<span class="si">)</span><span class="s2">"</span>
fancy_echo <span class="s2">"Preparing rbenv plugins..."</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="nv">$user_path</span>/.rbenv/plugins
git clone https://github.com/sstephenson/ruby-build.git <span class="nv">$user_path</span>/.rbenv/plugins/ruby-build
<span class="nb">echo</span> <span class="s1">'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
git clone https://github.com/sstephenson/rbenv-gem-rehash.git <span class="nv">$user_path</span>/.rbenv/plugins/rbenv-gem-rehash
<span class="c">## Ruby environment</span>
<span class="nv">RUBY_VERSION</span><span class="o">=</span><span class="s2">"2.2.3"</span>
fancy_echo <span class="s2">"Installing Ruby </span><span class="nv">$RUBY_VERSION</span><span class="s2"> ..."</span>
rbenv <span class="nb">install</span> <span class="nv">$RUBY_VERSION</span>
rbenv rehash
rbenv global <span class="nv">$RUBY_VERSION</span>
ruby <span class="nt">-v</span>
fancy_echo <span class="s2">"Gem update system ..."</span>
gem update <span class="nt">--system</span>
fancy_echo <span class="s2">"Echo .gemrc..."</span>
<span class="nb">echo</span> <span class="s1">'gem: --no-rdoc --no-ri'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.gemrc
gem <span class="nb">install </span>bundler
gem <span class="nb">install </span>backup
rbenv rehash
fancy_echo <span class="s2">"Export path ..."</span>
<span class="nb">echo</span> <span class="s2">"export PATH="</span><span class="nv">$PATH</span>:/usr/bin<span class="s2">""</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
<span class="nb">exec</span> <span class="nv">$SHELL</span>
</code></pre></div>
<p> </p>
<p>Your server is ready to run ROR application with those scripts.</p>
<p>Now We will write about deployment process for simple application.
As you know <a href="https://en.wikipedia.org/wiki/Ruby_on_Rails" target="_blank">ROR</a> has been developed with Ruby programming language, developing with <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">MVC(Model-View-Controller)</a> open source web framework and it includes principles like <a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank">DRY(Don’t Repeat Yourself)</a>, <a href="https://en.wikipedia.org/wiki/Convention_over_configuration" target="_blank">CoC(Convetion over configuration)</a> .</p>
<p>If you want to create rails application quickly, you should look the <a href="https://rubygems.org/gems/cybele" target="_blank">Cybele Ruby Gem</a> . This gem provides useful gem list and creates common pages for using in every application like user register, user login, update login and profile info, admin login. Thus you don’t repeat yourself on every new project. You can look the template Gemfile of Cybele gem, also from <a href="https://github.com/lab2023/cybele/blob/develop/templates/cybele_Gemfile">github</a>. Some useful deploy gems are on this file.
If you create project <code>rails new project_name</code> command or if you want to deploy project that is already initialized, my deploy commands is in this <a href="https://github.com/lab2023/recipes_matic">recipes_matic</a> gem, you should look that.</p>
<p>We will show deploy steps using with cybele gem.
<ol>
<li>Create project <code>$ cybele project_name</code></li>
<li>Edit deploy repo on this file <code>/config/deploy.rb</code>
<pre> set :repo_url, '<a href="mailto:git@github.com">git@github.com</a>:your_username/your_repo_name.git'</pre>
</li>
<li>Edit production deploy settings on this file <code> /config/deploy/production.rb </code>
<pre>
server <q>example.com</q>, user: <q>#{fetch(:local_user)}</q>, roles: %w{app db web}, primary: true, port: 22
set :rails_env, 'production'
set :branch, 'master'
set :project_domain, “example.com”
</pre>
</li>
<li>Edit staging deploy settings on this file <code>/config/deploy/staging.rb</code>
<pre>
server <q>staging.example.com</q>, user: <q>#{fetch(:local_user)}</q>, roles: %w{app db web}, primary: true, port: 22
set :rails_env, 'staging'
set :branch, 'develop'
set :project_domain, “staging.example.com”
</pre>
</li>
<li> Edit your_email address for to get info about the occurred errors
<br/><code>config/environments/production.rb </code><br/> <code>config/environments/staging.rb</code>
<pre>config.middleware.use ExceptionNotification::Rack,
:email => {
:email_prefix => <q>[project_name]</q>,
:sender_address => %{<q>Notifier</q> <<a href="mailto:notifier@project_name.com">notifier@project_name.com</a>>},
:exception_recipients => %w{<a href="mailto:your_email@address.com">your_email@address.com</a>}
}
</pre>
</li>
<li>Edit yout SMTP settings on those files <br/><code>config/settings/staging.yml</code><br/> <code>config/settings/production.yml</code></li>
<li>If you have private repo on github, run this commands in order for to access repo from server <br/><code>$ eval <code>ssh-agent -s</code></code><br/> <code>$ ssh-add </code></li>
<li>Let’s deploy our application with capistrano,
Check production server is ready to deployment
<code>$ bundle exec cap production deploy:check</code>
Setup nginx, postgresql, unicorn, <a href="http://meskyanichi.github.io/backup/v3/">backup</a>(backup gem for to get database backup before deploy) for production server.
<code>$ bundle exec cap production deploy:prepare</code>
Do deploy to production server.
<code>$ bundle exec cap production deploy</code></li>
</ol>
</p>
<p>Example Capfile file under project root directory</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1"># Load DSL and set up stages</span>
<span class="nb">require</span> <span class="s1">'capistrano/setup'</span>
<span class="c1"># Include default deployment tasks</span>
<span class="nb">require</span> <span class="s1">'capistrano/deploy'</span>
<span class="nb">require</span> <span class="s1">'capistrano/rails'</span>
<span class="nb">require</span> <span class="s1">'capistrano/bundler'</span>
<span class="nb">require</span> <span class="s1">'sshkit/sudo'</span>
<span class="nb">require</span> <span class="s1">'capistrano/maintenance'</span>
<span class="c1"># Include tasks from other gems included in your Gemfile</span>
<span class="c1"># For documentation on these, see for example:</span>
<span class="c1"># https://github.com/capistrano/rvm</span>
<span class="c1"># https://github.com/capistrano/rbenv</span>
<span class="c1"># https://github.com/capistrano/chruby</span>
<span class="c1"># https://github.com/capistrano/bundler</span>
<span class="c1"># https://github.com/capistrano/rails</span>
<span class="c1"># https://github.com/capistrano/passenger</span>
<span class="c1"># require 'capistrano/rvm'</span>
<span class="c1"># require 'capistrano/rbenv'</span>
<span class="c1"># require 'capistrano/chruby'</span>
<span class="c1"># require 'capistrano/bundler'</span>
<span class="c1"># require 'capistrano/rails/assets'</span>
<span class="c1"># require 'capistrano/rails/migrations'</span>
<span class="c1"># require 'capistrano/passenger'</span>
<span class="c1"># Load custom tasks from `lib/capistrano/tasks` if you have any defined</span>
<span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="s1">'lib/capistrano/tasks/*.rake'</span><span class="p">).</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span> <span class="n">import</span> <span class="n">r</span> <span class="p">}</span>
</code></pre></div>
<p>Example deploy.rb file under project config directory</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1"># config valid only for current version of Capistrano</span>
<span class="n">lock</span> <span class="s1">'3.4.0'</span>
<span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">'appname'</span>
<span class="n">set</span> <span class="ss">:local_user</span><span class="p">,</span> <span class="s1">'deploy'</span>
<span class="n">set</span> <span class="ss">:stages</span><span class="p">,</span> <span class="sx">%w(staging production)</span>
<span class="n">set</span> <span class="ss">:default_stage</span><span class="p">,</span> <span class="s1">'production'</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s2">"git@github.com:username/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:application</span><span class="p">)</span><span class="si">}</span><span class="s2">.git"</span>
<span class="c1"># Default branch is :master</span>
<span class="c1"># ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp</span>
<span class="c1"># Default deploy_to directory is /var/www/blog2</span>
<span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s2">"/home/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:local_user</span><span class="p">)</span><span class="si">}</span><span class="s2">/apps/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:application</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="c1"># Default value for :scm is :git</span>
<span class="n">set</span> <span class="ss">:scm</span><span class="p">,</span> <span class="ss">:git</span>
<span class="c1"># Default value for :format is :pretty</span>
<span class="c1"># set :format, :pretty</span>
<span class="c1"># Default value for :log_level is :debug</span>
<span class="c1"># set :log_level, :debug</span>
<span class="c1"># Default value for :pty is false</span>
<span class="n">set</span> <span class="ss">:pty</span><span class="p">,</span> <span class="kp">true</span>
<span class="c1"># Default value for :linked_files is []</span>
<span class="n">set</span> <span class="ss">:linked_files</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:linked_files</span><span class="p">,</span> <span class="p">[]).</span><span class="nf">push</span><span class="p">(</span><span class="s1">'config/database.yml'</span><span class="p">)</span>
<span class="c1"># Default value for linked_dirs is []</span>
<span class="n">set</span> <span class="ss">:linked_dirs</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:linked_dirs</span><span class="p">,</span> <span class="p">[]).</span><span class="nf">push</span><span class="p">(</span><span class="s1">'log'</span><span class="p">,</span> <span class="s1">'tmp/pids'</span><span class="p">,</span> <span class="s1">'tmp/cache'</span><span class="p">,</span> <span class="s1">'tmp/sockets'</span><span class="p">,</span> <span class="s1">'vendor/bundle'</span><span class="p">,</span> <span class="s1">'public/system'</span><span class="p">,</span> <span class="s1">'public/upload'</span><span class="p">,</span> <span class="s1">'public/images'</span><span class="p">,</span> <span class="s1">'public/seat_images'</span><span class="p">)</span>
<span class="c1"># Default value for default_env is {}</span>
<span class="c1"># set :default_env, { path: "/opt/ruby/bin:$PATH" }</span>
<span class="n">set</span> <span class="ss">:default_env</span><span class="p">,</span> <span class="p">{</span> <span class="ss">path: </span><span class="s1">'$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH'</span> <span class="p">}</span>
<span class="c1"># Default value for keep_releases is 5</span>
<span class="c1"># set :keep_releases, 5</span>
<span class="c1"># Look our recipes</span>
<span class="c1"># https://github.com/lab2023/recipes_matic</span>
<span class="nb">load</span> <span class="s1">'config/deploy/recipes/base.rb'</span>
</code></pre></div>
<p>We hope it is a useful post for you.</p>
Ruby on Rails Uygulamasının Capistrano 3 ile Kolayca Yayınlanması
http://lab2023.com/ruby-on-rails-uygulamasinin-capistrano-3-ile-kolayca-yayinlanmasi.html
2015-12-21T02:00:00+02:00
2023-11-02T16:54:44+03:00
lab2023
<p>Merhaba,</p>
<p>Sizlere Ubuntu-14.04 sunucusunu sıfırdan ayağa kaldırıp, kendi rails uygulamalarınızı sunucuya hızlı bir şekilde aktarabileceğiniz <a href="https://github.com/capistrano/capistrano" target="_blank">Capistrano</a> uygulamasından bahsedecek ve bazı kaynak kodlar paylaşacağız.</p>
<p>Kullandığımız capistrano'nun versiyonu 3.4'tür. Sunucu üzerinde kullandığımız ruby versiyonu ise 2.2.3'tür. Capistrano ‘nun kaynak kodlarına <a href="https://github.com/capistrano/capistrano" target="_blank">github</a> adresinden erişip göz atabilirsiniz.</p>
<p>Örnek olarak, <a href="https://www.netinternet.com.tr/vps-sunucular?aff=916">Netinternet</a> 'ten veya <a href="https://www.digitalocean.com/">DigitalOcean</a> 'dan alacağınız bir sunucuyu aşağıdaki bash scriptleri ile 2-3 saat içinde ayağa kaldırıp Nginx, Postgresql, Unicorn ayarlarını yaparak çalışır hale getirebilirsiniz.</p>
<p>Sunucuda ruby ortamı için temel kurulum scripti aşağıdaki gibidir. Bu script root kullanıcısı olarak bağlanıp çalıştırmalısınız.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="c">## Run this script with root user</span>
<span class="c">## Fancy echo</span>
fancy_echo<span class="o">()</span> <span class="o">{</span>
<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">%b</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
<span class="o">}</span>
fancy_echo <span class="s2">"Updating system packages ..."</span>
apt-get <span class="nt">-y</span> update
apt-get <span class="nt">-y</span> upgrade
fancy_echo <span class="s2">"Installing python-software-properties..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>python-software-properties
fancy_echo <span class="s2">"Installing software-properties-common..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>software-properties-common
fancy_echo <span class="s2">"Exporting language"</span>
<span class="nb">export </span><span class="nv">LANGUAGE</span><span class="o">=</span>en_US.UTF-8 <span class="o">&&</span> <span class="nb">export </span><span class="nv">LANG</span><span class="o">=</span>en_US.UTF-8 <span class="o">&&</span> <span class="nb">export </span><span class="nv">LC_ALL</span><span class="o">=</span>en_US.UTF-8 <span class="o">&&</span> locale-gen en_US.UTF-8 <span class="o">&&</span> dpkg-reconfigure locales
fancy_echo <span class="s2">"Installing libraries for common gem dependencies ..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
apt-get <span class="nb">install </span>git-core openssl curl libreadline-dev libxslt1-dev libcurl4-openssl-dev ruby-dev make make-doc
fancy_echo <span class="s2">"Installing nodejs ..."</span>
add-apt-repository <span class="nt">-y</span> ppa:chris-lea/node.js
apt-get <span class="nt">-y</span> update
apt-get <span class="nt">-y</span> <span class="nb">install </span>nodejs
apt-get <span class="nt">-y</span> <span class="nb">install </span>libxslt-dev libxml2-dev
fancy_echo <span class="s2">"Installing imagemagick ..."</span>
apt-get <span class="nb">install</span> <span class="nt">-y</span> imagemagick
fancy_echo <span class="s2">"Installing nginx ..."</span>
add-apt-repository <span class="nt">-y</span> ppa:nginx/stable
apt-get <span class="nt">-y</span> update
apt-get <span class="nt">-y</span> <span class="nb">install </span>nginx
service nginx start
fancy_echo <span class="s2">"Installing postgresql ..."</span>
apt-get <span class="nt">-y</span> <span class="nb">install </span>postgresql libpq-dev
</code></pre></div>
<p>Sunucuda deploy kullanıcısı için kurulum scripti aşağıdaki gibidir. Bu script'ide root kullanıcısı olarak bağlanıp çalıştırmalısınız.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="c"># Deploy group</span>
<span class="nv">deploy_group</span><span class="o">=</span>deploy
<span class="c"># Deploy user</span>
<span class="nv">deploy_user</span><span class="o">=</span>deploy
<span class="c"># Github usernames for access with ssh to deploy user</span>
<span class="nv">usernames</span><span class="o">=(</span>tayfunoziserikan ismailakbudak<span class="o">)</span>
<span class="c"># Check user is exist</span>
<span class="nb">id</span> <span class="nt">-u</span> <span class="nv">$deploy_user</span> &> /dev/null
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span>
<span class="k">then
</span><span class="nb">echo</span> <span class="s2">"* Add </span><span class="nv">$deploy_group</span><span class="s2"> group"</span>
groupadd <span class="nv">$deploy_group</span>
<span class="nb">echo</span> <span class="s2">"* Creating user </span><span class="nv">$deploy_user</span><span class="s2">"</span>
useradd <span class="nt">-m</span> <span class="nt">-g</span> <span class="nv">$deploy_group</span> <span class="nt">-s</span> /bin/bash <span class="nv">$deploy_user</span>
<span class="nb">echo</span> <span class="s2">"* Adding user </span><span class="nv">$deploy_user</span><span class="s2"> to sudoers"</span>
<span class="nb">chmod</span> +w /etc/sudoers
<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$deploy_user</span><span class="s2"> ALL=(ALL) ALL"</span> <span class="o">>></span> /etc/sudoers
<span class="nb">chmod</span> <span class="nt">-w</span> /etc/sudoers
<span class="k">else
</span><span class="nb">echo</span> <span class="s2">"* </span><span class="nv">$deploy_user</span><span class="s2"> user already exists"</span>
<span class="k">fi</span>
<span class="c"># Check user is exist, maybe some errors occured</span>
<span class="nb">id</span> <span class="nt">-u</span> <span class="nv">$deploy_user</span> &> /dev/null
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span>
<span class="k">then
</span><span class="nb">echo</span> <span class="s2">"* </span><span class="nv">$deploy_user</span><span class="s2"> user does not exists"</span>
<span class="k">else</span>
<span class="c"># Prepare ssh keys environment</span>
<span class="nb">echo</span> <span class="s2">"* Add .ssh directory to </span><span class="nv">$deploy_user</span><span class="s2">"</span>
<span class="nb">test</span> <span class="nt">-d</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span>
<span class="k">then
</span><span class="nb">mkdir</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="c"># change user permisisions</span>
<span class="c"># 700 => (owner read/write/execute, group none, other none)</span>
<span class="nb">chmod </span>700 /home/<span class="nv">$deploy_user</span>/.ssh
<span class="nb">chown</span> <span class="nv">$deploy_user</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="nb">chgrp</span> <span class="nv">$deploy_group</span> /home/<span class="nv">$deploy_user</span>/.ssh
<span class="k">fi
</span><span class="nb">echo</span> <span class="s2">"* Get usernames public keys from GitHub and add them to </span><span class="nv">$deploy_user</span><span class="s2"> authorized_keys"</span>
<span class="k">for </span>username <span class="k">in</span> <span class="k">${</span><span class="nv">usernames</span><span class="p">[@]</span><span class="k">}</span><span class="p">;</span> <span class="k">do
</span><span class="nv">name</span><span class="o">=</span><span class="nv">$username</span>.keys
wget https://github.com/<span class="nv">$name</span> <span class="nt">--no-check-certificate</span> <span class="nt">-O</span> <span class="nv">$name</span>
<span class="nb">cat</span> <span class="nv">$name</span> <span class="o">>></span> /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">rm</span> <span class="nv">$name</span> <span class="c"># remove temprory file</span>
<span class="k">done</span>
<span class="c"># change user permisisions</span>
<span class="c"># 600 => (owner read/write, group none, other none)</span>
<span class="nb">chmod </span>600 /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">chown</span> <span class="nv">$deploy_user</span> /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">chgrp</span> <span class="nv">$deploy_group</span> /home/<span class="nv">$deploy_user</span>/.ssh/authorized_keys
<span class="nb">echo</span> <span class="s2">"* Completed..."</span>
<span class="k">fi</span>
</code></pre></div>
<p> </p>
<p>Sunucuda deploy kullanıcısı için ruby ortamını hazırlama scripti aşağıdaki gibidir. Bu script deploy kullanıcısı olarak bağlanıp çalıştırmalısınız.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="c">## Run this command with deploy user</span>
<span class="c"># define user home path</span>
<span class="nv">user_path</span><span class="o">=</span>/home/deploy
<span class="c">## Fancy echo</span>
fancy_echo<span class="o">()</span> <span class="o">{</span>
<span class="nb">printf</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">%b</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span>
<span class="o">}</span>
fancy_echo <span class="s2">"Installing rbenv..."</span>
git clone git://github.com/sstephenson/rbenv.git <span class="nv">$user_path</span>/.rbenv
fancy_echo <span class="s2">"Writing rbenv path to bashrc ..."</span>
<span class="nb">echo</span> <span class="s1">'export PATH=\"$HOME/.rbenv/bin:$PATH\"'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
<span class="nb">echo</span> <span class="s1">'eval "$(rbenv init -)"'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
fancy_echo <span class="s2">"Exporting rbenv path..."</span>
<span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.rbenv/bin:</span><span class="nv">$PATH</span><span class="s2">"</span>
<span class="nb">eval</span> <span class="s2">"</span><span class="si">$(</span>rbenv init -<span class="si">)</span><span class="s2">"</span>
fancy_echo <span class="s2">"Preparing rbenv plugins..."</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="nv">$user_path</span>/.rbenv/plugins
git clone https://github.com/sstephenson/ruby-build.git <span class="nv">$user_path</span>/.rbenv/plugins/ruby-build
<span class="nb">echo</span> <span class="s1">'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
git clone https://github.com/sstephenson/rbenv-gem-rehash.git <span class="nv">$user_path</span>/.rbenv/plugins/rbenv-gem-rehash
<span class="c">## Ruby environment</span>
<span class="nv">RUBY_VERSION</span><span class="o">=</span><span class="s2">"2.2.3"</span>
fancy_echo <span class="s2">"Installing Ruby </span><span class="nv">$RUBY_VERSION</span><span class="s2"> ..."</span>
rbenv <span class="nb">install</span> <span class="nv">$RUBY_VERSION</span>
rbenv rehash
rbenv global <span class="nv">$RUBY_VERSION</span>
ruby <span class="nt">-v</span>
fancy_echo <span class="s2">"Gem update system ..."</span>
gem update <span class="nt">--system</span>
fancy_echo <span class="s2">"Echo .gemrc..."</span>
<span class="nb">echo</span> <span class="s1">'gem: --no-rdoc --no-ri'</span> <span class="o">>></span> <span class="nv">$user_path</span>/.gemrc
gem <span class="nb">install </span>bundler
gem <span class="nb">install </span>backup
rbenv rehash
fancy_echo <span class="s2">"Export path ..."</span>
<span class="nb">echo</span> <span class="s2">"export PATH="</span><span class="nv">$PATH</span>:/usr/bin<span class="s2">""</span> <span class="o">>></span> <span class="nv">$user_path</span>/.bashrc
<span class="nb">exec</span> <span class="nv">$SHELL</span>
</code></pre></div>
<p> </p>
<p>Bu scriptler ile sunucunuzu bir rails uygulamasını çalıştıracak duruma getirmiş olursunuz.</p>
<p>Şimdi bir rails uygulaması oluşturup, uygulamayı bir sunucuya aktarma işlemlerini anlatacağız.
<a href="https://en.wikipedia.org/wiki/Ruby_on_Rails" target="_blank">Ruby On Rails</a> bildiğiniz ruby dili ile, <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">MVC(Model-View-Controller)</a> mimari deseni ile geliştirilmiş ve bünyesinde <a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank">DRY(Don’t Repeat Yourself)</a>, <a href="https://en.wikipedia.org/wiki/Convention_over_configuration" target="_blank">CoC(Convetion over configuration)</a> gibi yazılım felsefelerini barındıran açık kaynak bir uygulama çatısıdır.</p>
<p>Hızlı bir Ruby On Rails uygulaması çıkarmak istiyorsanız size <a href="https://rubygems.org/gems/cybele" target="_blank">Cybele</a> ruby gem'ini öneririz. Bu gem bir uygulamada olması gereken kullanıcı giriş, bilgi güncelleme, yönetici tarafına giriş işlemleri gibi her projede kullanacağınız kısımlar hazır bir taslak olarak geliyor. Bu sayede önceden yazdığınız kodları tekrar yazmak zorunda kalmıyorsunuz. Cybele geminin taslak olarak getirdiği Gemfile 'ı <a href="https://github.com/lab2023/cybele/blob/develop/templates/cybele_Gemfile">github</a> adresinden inceleyebilirsiniz.
Sunucuya kolay bir şekilde uygulamayı taşımak için kullancağımız gemler bu Gemfile 'da yer almaktadır.
Eğer <code> rails new project_name</code> şeklinde sıfırdan bir proje oluşturursanız veya halihazırda bulunan bir projenizi sunucuya taşımak isterseniz, kullanacağımız komutlar dizisinin yer aldığı <a href="https://github.com/lab2023/recipes_matic">recipes_matic</a> gemini incelemenizi tavsiye ederiz.</p>
<p>Cybele ile oluşturduğumuz bir proje için bu adımları anlatacagız.
<ol>
<li>Proje oluştur <code>$ cybele project_name</code></li>
<li>Deploy repo bilgilerini düzenle <code>/config/deploy.rb</code>
<pre> set :repo_url, '<a href="mailto:git@github.com">git@github.com</a>:your_username/your_repo_name.git'</pre>
</li>
<li>Production deploy bilgilerini düzenle <code> /config/deploy/production.rb </code>
<pre>
server <q>example.com</q>, user: <q>#{fetch(:local_user)}</q>, roles: %w{app db web}, primary: true, port: 22
set :rails_env, 'production'
set :branch, 'master'
set :project_domain, “example.com”
</pre>
</li>
<li>Staging deploy bilgilerini düzenle <code>/config/deploy/staging.rb</code>
<pre>
server <q>staging.example.com</q>, user: <q>#{fetch(:local_user)}</q>, roles: %w{app db web}, primary: true, port: 22
set :rails_env, 'staging'
set :branch, 'develop'
set :project_domain, “staging.example.com”
</pre>
</li>
<li>Hata bildirimleri için email adresini düzenle
<br/> <code>config/environments/production.rb </code><br/> <code>config/environments/staging.rb</code>
<pre>config.middleware.use ExceptionNotification::Rack,
:email => {
:email_prefix => <q>[project_name]</q>,
:sender_address => %{<q>Notifier</q> <<a href="mailto:notifier@project_name.com">notifier@project_name.com</a>>},
:exception_recipients => %w{<a href="mailto:your_email@address.com">your_email@address.com</a>}
}
</pre>
</li>
<li>Aşağıdaki dosyalarda SMTP ayarlarını ayarla <br/><code>config/settings/staging.yml</code><br/><code>config/settings/production.yml</code></li>
<li>Github da bulunan private repolara lokaldeki gibi erismek icin şu komutları çalıştır
<br/><code>$ eval <code>ssh-agent -s</code></code> <br/><code>$ ssh-add </code></li>
<li>Gelelim terminalden çalıştırmamız gereken komutlar dizisine,Production sunucusunda ki deploy ortamının hazır olup olmadığını kontrol eder.
<code>$ bundle exec cap production deploy:check</code>
Production sunucusunda nginx, postgresql, unicorn, <a href="http://meskyanichi.github.io/backup/v3/">backup</a>(veritabanı yedek alma gemi) gibi ayarları yapar.
<code>$ bundle exec cap production deploy:prepare</code>
Production sunucusuna deploy işlemini gerçekleştirir.
<code>$ bundle exec cap production deploy</code></li>
</ol>
</p>
<p>Örnek dosyalarımızda şu şekilde olmalıdır.
Proje anadizininde bulunan Capfile örneği:</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1"># Load DSL and set up stages</span>
<span class="nb">require</span> <span class="s1">'capistrano/setup'</span>
<span class="c1"># Include default deployment tasks</span>
<span class="nb">require</span> <span class="s1">'capistrano/deploy'</span>
<span class="nb">require</span> <span class="s1">'capistrano/rails'</span>
<span class="nb">require</span> <span class="s1">'capistrano/bundler'</span>
<span class="nb">require</span> <span class="s1">'sshkit/sudo'</span>
<span class="nb">require</span> <span class="s1">'capistrano/maintenance'</span>
<span class="c1"># Include tasks from other gems included in your Gemfile</span>
<span class="c1"># For documentation on these, see for example:</span>
<span class="c1"># https://github.com/capistrano/rvm</span>
<span class="c1"># https://github.com/capistrano/rbenv</span>
<span class="c1"># https://github.com/capistrano/chruby</span>
<span class="c1"># https://github.com/capistrano/bundler</span>
<span class="c1"># https://github.com/capistrano/rails</span>
<span class="c1"># https://github.com/capistrano/passenger</span>
<span class="c1"># require 'capistrano/rvm'</span>
<span class="c1"># require 'capistrano/rbenv'</span>
<span class="c1"># require 'capistrano/chruby'</span>
<span class="c1"># require 'capistrano/bundler'</span>
<span class="c1"># require 'capistrano/rails/assets'</span>
<span class="c1"># require 'capistrano/rails/migrations'</span>
<span class="c1"># require 'capistrano/passenger'</span>
<span class="c1"># Load custom tasks from `lib/capistrano/tasks` if you have any defined</span>
<span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="s1">'lib/capistrano/tasks/*.rake'</span><span class="p">).</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span> <span class="n">import</span> <span class="n">r</span> <span class="p">}</span>
</code></pre></div>
<p>Proje config dizininde bulunan deploy.rb örneği:</p>
<div class="highlight"><pre class="highlight ruby"><code><span class="c1"># config valid only for current version of Capistrano</span>
<span class="n">lock</span> <span class="s1">'3.4.0'</span>
<span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s1">'appname'</span>
<span class="n">set</span> <span class="ss">:local_user</span><span class="p">,</span> <span class="s1">'deploy'</span>
<span class="n">set</span> <span class="ss">:stages</span><span class="p">,</span> <span class="sx">%w(staging production)</span>
<span class="n">set</span> <span class="ss">:default_stage</span><span class="p">,</span> <span class="s1">'production'</span>
<span class="n">set</span> <span class="ss">:repo_url</span><span class="p">,</span> <span class="s2">"git@github.com:username/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:application</span><span class="p">)</span><span class="si">}</span><span class="s2">.git"</span>
<span class="c1"># Default branch is :master</span>
<span class="c1"># ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp</span>
<span class="c1"># Default deploy_to directory is /var/www/blog2</span>
<span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s2">"/home/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:local_user</span><span class="p">)</span><span class="si">}</span><span class="s2">/apps/</span><span class="si">#{</span><span class="n">fetch</span><span class="p">(</span><span class="ss">:application</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="c1"># Default value for :scm is :git</span>
<span class="n">set</span> <span class="ss">:scm</span><span class="p">,</span> <span class="ss">:git</span>
<span class="c1"># Default value for :format is :pretty</span>
<span class="c1"># set :format, :pretty</span>
<span class="c1"># Default value for :log_level is :debug</span>
<span class="c1"># set :log_level, :debug</span>
<span class="c1"># Default value for :pty is false</span>
<span class="n">set</span> <span class="ss">:pty</span><span class="p">,</span> <span class="kp">true</span>
<span class="c1"># Default value for :linked_files is []</span>
<span class="n">set</span> <span class="ss">:linked_files</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:linked_files</span><span class="p">,</span> <span class="p">[]).</span><span class="nf">push</span><span class="p">(</span><span class="s1">'config/database.yml'</span><span class="p">)</span>
<span class="c1"># Default value for linked_dirs is []</span>
<span class="n">set</span> <span class="ss">:linked_dirs</span><span class="p">,</span> <span class="n">fetch</span><span class="p">(</span><span class="ss">:linked_dirs</span><span class="p">,</span> <span class="p">[]).</span><span class="nf">push</span><span class="p">(</span><span class="s1">'log'</span><span class="p">,</span> <span class="s1">'tmp/pids'</span><span class="p">,</span> <span class="s1">'tmp/cache'</span><span class="p">,</span> <span class="s1">'tmp/sockets'</span><span class="p">,</span> <span class="s1">'vendor/bundle'</span><span class="p">,</span> <span class="s1">'public/system'</span><span class="p">,</span> <span class="s1">'public/upload'</span><span class="p">,</span> <span class="s1">'public/images'</span><span class="p">,</span> <span class="s1">'public/seat_images'</span><span class="p">)</span>
<span class="c1"># Default value for default_env is {}</span>
<span class="c1"># set :default_env, { path: "/opt/ruby/bin:$PATH" }</span>
<span class="n">set</span> <span class="ss">:default_env</span><span class="p">,</span> <span class="p">{</span> <span class="ss">path: </span><span class="s1">'$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH'</span> <span class="p">}</span>
<span class="c1"># Default value for keep_releases is 5</span>
<span class="c1"># set :keep_releases, 5</span>
<span class="c1"># Look our recipes</span>
<span class="c1"># https://github.com/lab2023/recipes_matic</span>
<span class="nb">load</span> <span class="s1">'config/deploy/recipes/base.rb'</span>
</code></pre></div>
<p>Umarım faydalı bir yazı olmuştur.
Kolay gelsin.</p>
İkinci Rails Girls Denizli Etkinliği
http://lab2023.com/ikinci-rails-girls-denizli-etkinligi.html
2015-12-02T02:00:00+02:00
2023-11-02T16:54:44+03:00
lab2023
<p><a href="http://railsgirls.com/">Rails Girls</a> Finlandiya’da kurulmuş bir topluluktur. Amacı Rails kodlayan kadın sayısını artırmaktır.
Rails Girls topluluğu birçok ülkede başarılı projelere imza atmaktadır. Ülkemizde daha önce 2013 Ekim ayında
<a href="http://railsgirls.com/istanbul">Rails Girls İstanbul</a>, 2014 Mart ayında <a href="http://railsgirls.com/ankara">Rails Girls Ankara</a>, 2014 Mayıs ayında da <a href="http://railsgirls.com/denizli">Rails Girls Denizli</a> etkinlikleri
düzenlenmiştir. Türkiye’de 4. kez düzenlenen Rails Girls etkinliği <a href="http://lab2023.com/">Lab2023</a>’ün organizatörlüğünde Denizli ’de ikinci kez düzenleniyor.
2. Rails Girls Denizli etkinliği 11 - 12 Aralık tarihleri arasında Pamukkale Teknokent Konferans salonunda gerçekleşecek.
Etkinliğe katılım ve bilgi almak için <a href="http://railsgirls.com/denizli2015">railsgirls.com/denizli2015</a> adresini ziyaret edebilirsiniz.</p>
<p><a href="http://railsgirls.com/denizli2015"><img alt="railsgirlsdenizli2014" src="assets/images/articles/2015-12-02-rails-girls-denizli-etkinligi/railsgirls2014.jpg" /></a></p>
<p>Rails, Ruby programlama diliyle yazılmış, açık kaynak kodlu bir web uygulama geliştirme çerçevesidir.
Sade ve kısa bir sözdizimi sayesinde kullanıcı sayısı her geçen gün artmaktadır. Bu etkinliğin amacı her
yaştan kadının Rails’i tanıması, web dünyasını öğrenmesi ve küçük web uygulamaları yapabilmeleridir.
Bu uygulamalar sayesinde kadınlar kod yazmanın zor olmadığını farketmeye başlayacak ve ön yargılarından
kurtulacaklardır. Etkinliğe yanlarında bir kadının eşlik etmesi halinde konuyla ilgilenen erkekler de katılabiliyor.</p>
<p>Rails Girls etkinliğini en güzel yanlarından birisi de Rails konusunda uzman kişilerin etkinlik sırasında
size mentorluk etmesi ve yönlendirmesi. Etkinliğe katılmak için programcılık bilgisine sahip olmanıza gerek yoktur.</p>
<p><a href="http://lab2023.com/">Lab2023</a> organizatörlüğünde 11 - 12 Aralık 2015 tarihleri arasında Denizli’de <a href="http://pauteknokent.com.tr/teknokent/">Pamukkale Teknokent</a>, <a href="https://www.bulutfon.com/?ref=1">Bulutfon</a>, <a href="http://www.netinternet.com.tr/panel/aff.php?aff=916">Netinternet</a>, <a href="http://www.soroptimistdenizli.org/">Denizli Soroptimistik Kulübü</a>,
<a href="http://www.denizlihs.org/">Denizli Hackerspace</a> ve <a href="http://lab2023.com/">Lab2023</a> ‘ün sponsorluk destekleriyle gerçekleşecek olan Rails Girls etkinliğinin programı şu şekildedir.</p>
<ul>
<li><p>Cuma akşamı katılımcılar ve mentörler ile tanışma ve kurulum partisi yapılacaktır. Bu partide cumartesi günü neler yapılacağı
anlatılacak ve katılımcıların bilgisayarlarına gerekli programların kurulması sağlanacaktır.</p></li>
<li><p>Cumartesi günü ise eğitime başlanacak ve küçük uygulamalar yapılarak bir proje ortaya çıkarılacak.</p></li>
</ul>
<p>Bu güzel etkinliğe son katılım tarihi, 6 Aralık 'tır.</p>
<p>Katılmak için <a href="http://railsgirls.com/denizli2015">railsgirls.com/denizli2015</a> adresindeki formu doldurmanız yeterli.</p>
<hr>
<p><a href="http://railsgirls.com/denizli2015"><img alt="railsgirlsdenizli" src="assets/images/articles/2015-12-02-rails-girls-denizli-etkinligi/railsgirlsdenizli2015.png" /></a></p>
Popüler front-end araçları
http://lab2023.com/populer-front-end-araclari.html
2015-11-24T02:00:00+02:00
2023-11-02T16:54:44+03:00
lab2023
<p>Teknolojinin geldiği konum ve ulaşılabilirliğinin artmasıyla web teknolojileri hayatımızda farklı bir noktaya yükseldi. Genel anlamda gelişen teknolojide önyüz kodlayıcıları için faydalı bazı araçları tanıtacağım.</p>
<h3 id="bower">Bower</h3>
<p><img alt="bower" src="assets/images/articles/25-09-08-tools-for-front-end/bower.jpg" /></p>
<p>Bower bir front-end kütüphanesidir. Diğerlerinden ayıran özelliği ise projemizde kullanacağımız paketi kurduğumuzda bu paketin çalışması için gerekli olan diğer paketleri de kurması.</p>
<p>Mesela bootstrap’ı indirdiğimizde jquery’ide indiriyor.</p>
<h3 id="kurulumu">Kurulumu:</h3>
<p>Npm kullanarak kuracağız. Bower paket yöneticisini kullanabilmemiz için bilgisayarımızda <a href="https://nodejs.org/en/">nodejs</a> ve <a href="https://git-scm.com/">git</a>’in kurulu olması gerekiyor.</p>
<div class="highlight"><pre class="highlight shell"><code>npm <span class="nb">install</span> <span class="nt">-g</span> bower
</code></pre></div>
<h3 id="paket-kurulumu">Paket Kurulumu:</h3>
<p>Şimdi binlerce paket içerisinden istediğimizi kullanabiliriz.</p>
<div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install </span>bootstrap
</code></pre></div>
<p>Çıktısı:</p>
<p><img alt="bower" src="assets/images/articles/25-09-08-tools-for-front-end/bower-bootstrap.jpg" /></p>
<p>Kulanmak istediğimiz paketin tam adını, github proje linkini, proje linkini ya da github proje uzantısını yazarak kurabiliriz.</p>
<div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install </span>twbs/bootstrap
</code></pre></div><div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install </span>git://github.com/twbs/bootstrap
</code></pre></div><div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install </span>http://example.com/script.js
</code></pre></div>
<h3 id="init">init</h3>
<p>Bower’ın bir diğer güzel özelliği ise projemizde kullandıgımız paketleri</p>
<div class="highlight"><pre class="highlight shell"><code>bower init
</code></pre></div>
<p>komutu ile json dosyası olarak saklaması ve dosya sayesinde aynı paketleri baska projelerde de kullanabilmesi. Bu sayede farklı bir projede yine aynı paketleri kullanacaksak yaptığımız işlem sayısını azaltmıs oluyoruz.</p>
<p>Oluşturduğumuz bu bower.json dosyasını kullanmak istediğimiz projenin dizinine ekleyip</p>
<div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install</span>
</code></pre></div>
<p>kodunu çalıştırmamız yeterli oluyor.</p>
<p>Diyelim ki bower init komutunu çalıştırdıktan sonra projeye yeni paketler dahil ettik ve bunlarıda .json dosyamıza eklemek istiyoruz. Bu işlemide</p>
<div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install </span>paket-adi <span class="nt">--save</span>
</code></pre></div>
<p>ya da</p>
<div class="highlight"><pre class="highlight shell"><code>bower <span class="nb">install </span>paket-adi <span class="nt">-s</span>
</code></pre></div>
<p>komutu ile yapabiliyoruz.</p>
<h3 id="list">list</h3>
<p>Projenizde kullandığınız paketleri</p>
<div class="highlight"><pre class="highlight shell"><code>bower list
</code></pre></div>
<p>komutuyla konsolda listeyebilirsiniz.</p>
<h3 id="search">search</h3>
<p>Aradığınız paketin adıyla arama yaptırabilirsiniz.</p>
<div class="highlight"><pre class="highlight shell"><code>bower search paket-adi
</code></pre></div>
<p>Çıktısı:
<img alt="bower" src="assets/images/articles/25-09-08-tools-for-front-end/bower-search.jpg" /></p>
<h3 id="update">update</h3>
<p>Kurduğumuz paketleri güncellemek istersek</p>
<div class="highlight"><pre class="highlight shell"><code>bower update
</code></pre></div>
<p>komutu ile kurulu bütün paketleri,</p>
<p>çıktısı:</p>
<p><img alt="bower" src="assets/images/articles/25-09-08-tools-for-front-end/bower-update.jpg" /></p>
<div class="highlight"><pre class="highlight shell"><code>bower update paket-adi
</code></pre></div>
<p>ile de sadece güncellemek istediğimiz paketi güncelletebiliyoruz.</p>
<p>çıktısı:</p>
<p><img alt="bower" src="assets/images/articles/25-09-08-tools-for-front-end/bower-update-name.jpg" /></p>
<h3 id="uninstall">uninstall</h3>
<p>Kurduğumuz paketi projeden kaldırmak istersek,</p>
<div class="highlight"><pre class="highlight shell"><code>bower uninstall paket-adi
</code></pre></div>
<p>komutunu kullanıyoruz, json dosyasından da kaldırmak için –save komutunu eklememiz gerekiyor.</p>
<p>Bower’ın özellikleri tabii ki bu kadar değil. <a href="http://bower.io/">www.bower.io</a> adresinden bütün detaylara ulaşabilirsiniz.</p>
<h3 id="gulp">Gulp</h3>
<p><img alt="gulp" src="assets/images/articles/25-09-08-tools-for-front-end/gulp.jpg" /></p>
<p>Bu araç sayesinde projemizin rutin işlerini otomatize edebiliyoruz. Hepimiz web sayfasını yayına almadan önce bazı bazı işlemleri tekrar tekrar yapıyoruz. Kullandığımız fotoğrafların boyutlarını değiştirmek, css dosyamızı küçültmek, yazdığımız js’leri tek dosya haline getirmek gibi. Bu ve bunlar gibi rutin işlerimizi gulp sayesinde otomatize edebiliriz.</p>
<p>Şimdi ilk olarak gulpjs'i makinemize kuralım. Gulp da bower ve grunt gibi npm’e gereksinim duyuyor. Gulp kullanacağımız modülleri npm veritabanından çekiyor.</p>
<h3 id="kurulumu">Kurulumu:</h3>
<div class="highlight"><pre class="highlight shell"><code>npm <span class="nb">install </span>gulp <span class="nt">-g</span>
</code></pre></div>
<p>Projemize ya da localimize kurduktan sonra gulpfile.js dosyası oluşturup yaptıracağımız görevleri buraya yazıyoruz.</p>
<p><img alt="gulp" src="assets/images/articles/25-09-08-tools-for-front-end/gulp-js.jpg" /></p>
<p>Verdiğimiz görevler için kurulan plugin ya da paketler ise node_modules/ klasörü altına ekleniyor.</p>
<p>Sonrasında ise işimize yarayacak paketleri bulup entegre edeceğiz. Bu paketleride istersek <a href="http://gulpjs.com/plugins/">gulpjs</a>’in sayfasından istersekte <a href="https://www.npmjs.com/">npmjs</a>’in sayfasından bulabılırız.</p>
<div class="highlight"><pre class="highlight shell"><code>
npm <span class="nb">install </span>paket-adi
</code></pre></div>
<p>yukarıdakı komut satırıda paketleri kurmaya yarıyor. Paket kurulumundan sonra kurduğumuz paketin parametrelerini gulpfile.js dosyamıza eklememiz gerekiyor.
Aşağıdaki gulpfile.js dosyasında <a href="https://www.npmjs.com/package/gulp-concat">gulp-concat</a>, <a href="https://www.npmjs.com/package/gulp-coffee">gulp-coffee</a> ve <a href="https://www.npmjs.com/package/gulp-uglify">gulp-uglify</a> eklentileri kullanılmış.</p>
<p><img alt="gulp" src="assets/images/articles/25-09-08-tools-for-front-end/gulp-ext.jpg" /></p>
<p>Kurduğumuz paketler proje dosyamızın içindeki node_modules dosyasına ekleniyor.</p>
<p>İstediğimiz paketleri kurduktan ve gulpfile.js dosyasına ekledikten sonra ise komut satırına</p>
<div class="highlight"><pre class="highlight shell"><code>gulp
</code></pre></div>
<p>yazdığımızda bütün görevleri çalıştırıyor.</p>
<p>Gulpjs için daha detaylı bilgiye <a href="http://gulpjs.com/">www.gulpjs.com</a> adresinden ulaşabilirsiniz.</p>
<h3 id="grunt">Grunt</h3>
<p><img alt="grunt" src="assets/images/articles/25-09-08-tools-for-front-end/grunt.jpeg" /></p>
<p>Gruntta tıpkı gulpjs gibi bir iş kolaylaştırıcı. Kullandığı modülleri npm veri tabanından çekiyor.</p>
<h3 id="kurulumu">Kurulumu:</h3>
<div class="highlight"><pre class="highlight shell"><code> npm <span class="nb">install </span>grunt
</code></pre></div>
<p>Grunt için kullanacağımız plug-in ya da modüller içinde</p>
<div class="highlight"><pre class="highlight shell"><code>npm <span class="nb">install </span>paket-adi
</code></pre></div>
<p>komutunu kullabiliyoruz.</p>
<p>Kurduktan sonra node_modules/ klasörü oluşturuyor, bu klasörde kuracağımız paket ve pluginler tutuluyor.</p>
<p>Şimdi grunt.js dosyası oluşturup görevlerimizi oraya yazacağız. Genel olarak gulpjs'le aynı yapıda. Farklılıkları görev yazma aşamasında ortaya çıkıyor.</p>
<p><img alt="grunt" src="assets/images/articles/25-09-08-tools-for-front-end/grunt-sample.jpeg" /></p>
<p>Yukarıda kaynağı grunt-project dizininde bulunan sample.js dosyasını add-sample.min.js dosyasına dönüştürecek görev için yazılmış kodlar yer alıyor.</p>
<p>Kurduğumuz plugin'lerin açıklamaları ve parametreleri github ya da kendi sayfalarında yazıyor.</p>
<p>Pluginleri <a href="http://gruntjs.com/plugins">gruntjs</a>’in sayfasından ya da <a href="https://www.npmjs.com/">npmjs</a>’in sayfasından bulup kurabilirsiniz. Kullanabileceğimiz bütün metotlara gruntjs'in <a href="http://gruntjs.com/api/grunt">API</a> sayfasından ulaşabilirsiniz.</p>
<p>Daha detaylı bilgi için <a href="http://gruntjs.com/">www.gruntjs.com</a> adresini inceleyebilirsiniz.</p>
<h3 id="yeoman">Yeoman</h3>
<p><img alt="yeoman" src="assets/images/articles/25-09-08-tools-for-front-end/yeoman.jpeg" /></p>
<p>Yeoman npm'i kullanarak sürecimizi hızlandıran bir diğer front-end aracımız. Projemiz için template olusturuyor.</p>
<p>Bilgisayarımıza kurabilmek için node.js ve git in yüklü olması gerekıyor.</p>
<h3 id="kurulumu">Kurulumu</h3>
<div class="highlight"><pre class="highlight shell"><code>npm <span class="nb">install </span>yo
</code></pre></div>
<p>komutuyla yükleyebiliyoruz.</p>
<p>Yeoman gruntjs ve bower araçlarını default olarak projeye dahil ediyor.</p>
<p>oluşturmak istediğimiz projede kullanacağımız paketleri <a href="http://yeoman.io/generators/">generators</a> ya da <a href="https://www.npmjs.com/">npmjs</a> sayfasından bulup inceleyebilirsiniz.</p>
<p>Paket kurulumu için:</p>
<div class="highlight"><pre class="highlight shell"><code>npm <span class="nb">install</span> <span class="nt">--global</span> paket-adi
</code></pre></div>
<p>Paketi kurup yo komutunu çalıştırarak ya da</p>
<div class="highlight"><pre class="highlight shell"><code>yo paket-adi
</code></pre></div>
<p>komutunu çalıştırarak template oluşturabiliriz.</p>
<p>Çalıştırmak için komut satırına:</p>
<div class="highlight"><pre class="highlight shell"><code>yo
</code></pre></div>
<p>komutunu yazıyoruz.</p>
<p><img alt="yeoman" src="assets/images/articles/25-09-08-tools-for-front-end/yeoman-yo.jpeg" /></p>
<p>Yukarıda yo komutundan sonra sistemde yüklü template yapılarını secip kullanabileceğimiz gibi install a generator komutunu seçerekte yeni template yükleyebiliyoruz.</p>
<p>Yukarıda bahsettiğim bütün araçlar paket kurmak için npm'e ihtiyac duyuyor. Bu yuzden plug-in ve paket kurulumları aynı.</p>
<p>Yeoman ile html5 template’i oluşturmak istiyorsak</p>
<div class="highlight"><pre class="highlight shell"><code>npm <span class="nb">install</span> <span class="nt">--global</span> generator-h5bp
</code></pre></div>
<p>komutunu kullanarak önce html5 paketini indiriyoruz. Sonrada</p>
<div class="highlight"><pre class="highlight shell"><code>yp h5bp
</code></pre></div>
<p>komutu ile template oluşturuyoruz.</p>
<p>Detaylı bilgi için <a href="http://yeoman.io/">www.yeoman.com</a> adresini inceleyebilirsiniz.</p>
What is vagrant and properties of vagrant?
http://lab2023.com/what_is_vagrant_and_properties_of_vagrant.html
2014-12-25T02:00:00+02:00
2023-11-02T16:54:44+03:00
lab2023
<h3 id="properties-of-vagrant">Properties of Vagrant</h3>
<p><code>Vagrant</code> is a tool which runs your application in a virtual machine, which means
you can create your project environment in a virtual machine. Thanks to Vagrant, you can clone your local environment in a virtual machine.
So, when you send your project to <code>server</code>, you don’t see any bugs or errors on your server.
On the other hand, vagrant is useful while you are working in a team.</p>
<h3 id="how-to-set-up-vagrant-on-ubuntu-desktop">How to Set Up Vagrant on Ubuntu Desktop</h3>
<p>To install and use vagrant, you should follow the steps below respectively.</p>
<p>Let’s look, how to set up and use <code>Vagrant in Ubuntu desktop</code>,</p>
<ul>
<li>Install Vagrant</li>
<li>Create Vagrant folders</li>
<li>Install precise32 box</li>
<li>Set up new virtual machine</li>
<li>Install virtual machine configuration</li>
</ul>
<h3 id="1-install-vagrant">1) Install Vagrant</h3>
<p>Installing vagrant on your Ubuntu desktop is very easy. Open your terminal and write the command below.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>vagrant
...
</code></pre></div>
<h3 id="2-create-vagrant-folders">2) Create Vagrant Folders</h3>
<p>Continue on terminal, write below commands,</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span><span class="nb">mkdir </span>Vagrant
<span class="nv">$ </span><span class="nb">mkdir </span>Vagrant/Projects
<span class="nv">$ </span><span class="nb">mkdir </span>Vagrant/Projects/VM_169.x
</code></pre></div>
<h3 id="3-install-precise32-box">3) Install Precise32 Box</h3>
<p>Precise32 box is important on ubuntu desktop, because thanks to this box you can modify your virtual machine.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span><span class="nb">cd </span>Vagrant/Projects/VM_169.x
<span class="nv">$ </span>vagrant box add precise32 http://files.vagrantup.com/precise32.box <span class="nt">--provider</span> virtualbox
...
</code></pre></div>
<p>After install, you can check with,</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant box list
precise32 <span class="o">(</span>virtualbox, 0<span class="o">)</span>
</code></pre></div>
<h3 id="4-create-new-virtual-machine">4) Create New Virtual Machine</h3>
<p>For create new virtual machine, you should initialize precise32 box,</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant init precise32
</code></pre></div>
<p>When you write above command, you get warning about it, this means include <code>Vagrantfile</code>.</p>
<h3 id="5-install-virtual-machine-configuration">5) Install Virtual Machine configuration</h3>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>wget https://raw.github.com/saasbook/courseware/master/vm-setup/configure-image-0.10.3.sh
</code></pre></div>
<p>You should change permission to executable for virtual machine configuration</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span><span class="nb">chmod</span> +x configure-image-0.10.3.sh
</code></pre></div>
<ul>
<li>Run the virtual machine with </li>
</ul>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant up
</code></pre></div>
<ul>
<li>Connecting with virtual machine</li>
</ul>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant ssh
Welcome to Ubuntu 12.04 LTS <span class="o">(</span>GNU/Linux 3.2.0-23-generic-pae i686<span class="o">)</span>
<span class="k">*</span> Documentation: https://help.ubuntu.com/
New release <span class="s1">'14.04.1 LTS'</span> available.
Run <span class="s1">'do-release-upgrade'</span> to upgrade to it.
Welcome to your Vagrant-built virtual machine.
Last login: Sun Oct 12 09:36:51 2014 from 10.0.2.2
vagrant@precise32:~<span class="nv">$ </span>
</code></pre></div>
<ul>
<li>Run virtual machine configuration, </li>
</ul>
<div class="highlight"><pre class="highlight shell"><code>vagrant@precise32:~<span class="nv">$ </span>/vagrant/configure-image-0.10.3.sh
Enter password to be used <span class="k">for </span><span class="nb">sudo </span>commands:
</code></pre></div>
<p>you should enter a password for commands above.</p>
<p>If you finish work on virtual machine, you write below commands for exit or shut down virtual machine</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant <span class="nb">suspend</span>
<span class="nv">$ </span>vagrant resume
<span class="nv">$ </span>vagrant halt
</code></pre></div>
<p>Or if you want to remove all things from virtual machine</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant destroy
</code></pre></div>
<p>But for building your project again only the command below is enough.</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant up
</code></pre></div>
<ul>
<li>When I say <code>Vagrant</code> is useful for working in a team, look <a href="https://vagrantcloud.com/">Vagrant Cloud</a>.</li>
</ul>
<p>You can create account and share your vagrant environment with anyone with <code>vagrant cloud</code>.
After create your account, open your terminal,</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant login
...
</code></pre></div>
<p>Write e-mail or username and password for vagrant cloud, then</p>
<div class="highlight"><pre class="highlight shell"><code><span class="nv">$ </span>vagrant share
</code></pre></div>
<p>For more detail about Vagrant, you can look ;</p>
<ul>
<li><a href="http://docs.vagrantup.com/v2/getting-started/index.html">Vagrant</a> </li>
<li><a href="https://github.com/saasbook/courseware/wiki/Setting-Up-Vagrant-Environment-on-Ubuntu-Platform">Vagrant on Ubuntu</a></li>
</ul>
<p>or,</p>
<p>if you want to read same article with details in Turkish, you can read it <a href="http://lab2023.com/vagranta-giris.html">here</a>.</p>
<p>That’ s all.</p>