2015년 10월 14일 수요일

안드로이드 M 개발자 프리뷰 정리

M 개발자 프리뷰
SDK 툴
에뮬레이터
디바이스 이미지
개발문서
샘플코드 포함

developer.android.com/preview

올바른 버전의 SDK 툴을 미리 설치하지 않으면 특히 fast boot tool
시스템이미지를 올리는 도중에 오류가 발생할 수 있다.

개발자 프리뷰 SDK는
안드로이드 스튜디오 1.3 버전 이상에서 다운가능

테스트
developer.android.com/preview/behavior-changes.html

Doze Mode 테스트
$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
$ adb shell dumpsys deviceidle -h

App Standby Mode
$ adb shell dumpsys battery unplug
$ adb shell am set-idle <packageName> true
$ adb shell am set-idle <packageName> false
$ adb shell am get-idle <packageName>

지문인식 테스트
$ adb -e emu finger touch 1

What's Next?
안드로이드 M 개발자 프리뷰 (한글)
developer.android.com/preview

이슈 트래커
goo.gl/Blq1eJ

GDG Korea 커뮤니티 페이지
facebook.com/gdgkorea

2015년 10월 13일 화요일

레일스에서 무한 스크롤링 : 기본

Pagination은 매우 일반적이고 널리 사용되는 네비게이션 기술이다. 그리고 그만한 이유가 있다. 무엇보다도, 성능을 고려해보자. 하나의 쿼리에 모든 가능한 레코드를 로딩하는 것은 매우 큰 비용이 소모된다. 게다가 사용자는 가장 최근의 레코드들 중 몇개에만 흥미가 있을 수 있다. (즉 블로그에서 가장최근의 포스트들) 그리고 모든 레코드가 로딩되고 렌더링되는데까지 기다리길 원하지 않는다. 또한 Pagination은 컨텐츠로 페이지를 넘치게 하지 않음으로써 페이지를 읽기 쉽게 만든다.

근래에는 많은 웹사이트가 infinite scrolling(또는 endless page)라고 불리는 약간씩 다른 기술을 사용한다. 기본적으로, 사용자가 페이지를 스크롤하면 AJAX를 이용해 비동기적으로 더 많은 레코드가 로딩된다. 이러한 방식으로 스크롤링은 사용자가 끊임없이 '다음 페이지'링크를 클릭하는 것보다 더 자연스럽고 쉬울 것이다.

이 글에서는 클래식 pagination 대신에 무한 스크롤을 어떻게 구현하는지 설명할 것이다.

먼저, will_paginate gem을 사용하는 기본 pagination을 구현하는 데모 프로젝트를 준비할 것이다. 이 튜토리얼을 통해 작업해나가면서 pagination은 무한 스크롤링이 되어갈 것이다. 이는 루비와 함게 몇몇 JavaScript(와 CoffeeScript)를 작성하는 것을 요구한다.

제공되는 솔루션은 사용자가 브라우저에 javascript를 disable 시켰다면 기본 pagination으로 후퇴시킬 것이다. 결국, 우리 뷰는 실질적으로 어떤 수정도 요구하지 않으므로 어떤 웹사이트에서도 쉽게 구현할 수 있다.

변환될 다른 아이템들은 다음과 같다:

  • 스크롤링 대신에 "Load more" 버튼을 어떻게 구현할 것인가, SitePoint에서 사용되는 것과 매우 유사하게
  • 몇몇 골치거리와 잠재적인 문제들, 특별히 History API 와 scroll spying이 우리를 도울 수 있다.
동작하는 데모는 http://sitepoint-infinite-scrolling.herokuapp.com 에서 볼 수 있다.

소스 코드는 GitHub에서 받을 수 있다.

좋아보이는가? 시작해보자.

프로젝트 준비하기

이 문서 작성시에는 Rails 3.2.16을 사용하였으나 Rails 4로 동일한 솔루션을 구현할 수 있다.

$ rails new infinite_scrolling -T


여기서 T는 test suite를 생성하는 것을 생락하고자 한다는 의미이다(필자는 RSpec을 선호하지만 이 플래그를 제거할 수 있다).

우리는 쓸모있는 몇몇 gem을 연결할 것이다.

Gemfile


gem 'will_paginate', '~> 3.0.5'
gem 'betterlorem', '~> 0.1.2'
gem 'bootstrap-sass', '~> 3.0.3.0'
gem 'bootstrap-will_paginate', '~> 0.0.10'

will_paginate 는 레코드에 페이지를 잘 매길 것이다. 다음 섹션에서 이 gem에 대해 더 자세히 다룰 것이다. betterlorem 은 우리 레코드에 데모 텍스트를 생성한다. "Lorem lpsum" 텍스트를 생성하는 다른 유사한 gem들이 있지만 우리의 경우엔 이 gem이 가장 편리하다고 생각한다(우리는 view에서가 아니라 seeds.rb에서 그것을 사용할 것이다).

상을 받을 디자인을 만들어 내는 것은 아무 의미가 없다. 그래서 빠르고 쉬운 솔루션으로 우리는 Twitter Bootstrap 3를 사용할 것이다(무게면에서 보자면 가장 작은 것은 아니지만). bootstrap-sass gem을 우리 레일스 프로젝트에 추가했다. bootstrap-will_paginate 는 pagination 자체를 위한 몇몇 Bootstrap 스타일을 포함하고 있다.

다음을 실행하는 것을 잊지마라.

$ bundle install

다음을 application.js에 추가하고

// = require bootstrap

다음은 application.css.scss 에 모든 Bootstrap 스타일과 스크립트들을 포함하기 위해 추가하자.

@import "bootstrap";

물론, 실제 애플리케이션에서는 오직 필요한 컴포넌트만을 선택할 것이다.

The Model

하나의 테이블 :Post만 존재하는 상태이다. 간단한 구조이면 다음의 컬럼들을 포함하고 있다.
  • id (integer, primary key)
  • title (string)
  • body (text)
  • created_at (datetime)
  • updated_at (datetime)

실행하기

$ rails g model Post title:string body:text
$ rake db:migrate

우리는 적절한 migration을 생성하고 그것을 데이터베이스에 적용할 것이다.

다음 과정은 몇몇 테스트 데이터를 생성하는 것이다. 가장 쉬운 바법은 seeds.rb를 사용하는 것이다.

seeds.rb


50.times { |i| Post.create(title: "Post #{i}", body: BetterLorem.p(5, false, false)) }
이것은 BetterLorem에 의해 생성된 body를 가진 50개의 post를 생성한다. 각각의 생성된 컨텐츠의 집합은 5개의 paragraph들로 구성된다. 마지막 두개의 아규먼트는 BetterLorem에게 p 태그로 텍스트를 감싸고 trainling period를 포함하도록 지시한다.

실행하기

$ rake db:seed

이것은 데이터베이스에 몇몇 test 포스트들을 덧붙이다. 대단하다!

마지막은 대응하는 뷰들과 함께(index.html.erbshow.html.erb) indexshow 메소드를 가진 PostController를 생성하는 것이다.

routes.rb

resources :posts, only: [:index, :show]
root to: 'posts#index'

마지막에는 Rails 3를 사용한다면, public/index.html 파일을 제거해라.

The Controller

이제 재미있는 파트로 넘어갈 준비가 되었다. 먼저, 잘린 body를 가진 페이지가 매겨진 포스트들을 디스플레이해보자. 이를 위해, will_paginate를 사용할 것이다. - a simple yet convenient gem by Mislav Marohnić that works with Ruby on Rails, Sinatra, Merb, DataMapper and Sequel.

이 솔루션에 대한 대안도 있다. - kaminari by Akira Matsuda that is more powerful and more sophisticated. You can also give it a try. Basically, it doesn’t matter which gem you use.

우리의 컨트롤러에서:

post_controller.rb


@posts = Post.paginate(page: params[:page], per_page: 15).order('created_at DESC')

paginate 메소드에 대한 호출은 page 옵션을 받아서 GET 파라미터가 요청한 페이지 번호를 받아오는데 사용하도록 지시한다. per_page 옵션은 페이지당 표시할 레코드의 수를 지정한다. per_page 옵션은 아래처럼 전체 모델에 대해 지정하거나 전체 프로젝트에 대해 지정할 수 있다.

post.rb


class Post
  self.per_page = 10
end
will_paginate.rb(in an initializer)

WillPaginate.per_page = 10

paginate 메소드는 ActiveRecord::Relation을 리턴하므로 우리가 order 메소드를 호출해서 묶을 수 있다.

The View

index.html.erb


<div class="page-header">
  <h1>My posts</h1>
</div>

<div id="my-posts">
  <%= render @posts %>
</div>

<div id="infinite-scrolling">
  <%= will_paginate %>
</div>

page header는 Bootstrap class의 help로 지정되었다. 다음 블록, #my-posts는 우리의 페이지가 지정된 포스트를 포함한다. render @posts를 사용하여 _post.html.erb partial을 사용해 array로부터 각 포스트를 디스플레이한다. 마지막 블록 #infinite-scrolling은 pagination control들을 포함한다.

will_paginate는 @posts를 페이지 지정하기 원한다는 것을 이해할 만큼 영리하다는 것을 주목해라. 명시적으로 이렇게 지정할 수도 있다: will_paginate @posts.

여기 우리의 partial이 있다.

_post.html.erb


_post.html.erb
<div>
  <h2><%= link_to post.title, post_path(post) %></h2>

  <small><em><%= post.timestamp %></em></small>

  <p><%= truncate(strip_tags(post.body), length: 600) %></p>
</div>
우리는 모든 post를 div로 둘러싸고 있다. 그러면 전체 post를 읽기 위하여 링크처럼 동작하는 타이틀을 디스플레이할 수 있다. timestamp는 post가 생성된 때를 가리킨다. timestamp 함수는 아래와 같이 model 내에 정의되어 있는 함수이다.

post.rb

def timestamp
  created_at.strftime('%d %B %Y %H:%M:%S')
end

마지막으로 우리는 post로부터 모든 tag들을 제거하기 위해 strip_tags 함수를 사용하였고 600개의 symbol 만을 남기기 위해 truncate 메소드를 사용한다. 이로써 view를 가지고 하는 작업은 끝이났다(layout.html.erbshow.html.erb를 위한 markup은 중요하지 않으므로 생략한다. GitHub repo에 있는 것을 참고하라.)

Infinite Scrolling

이제 무한 스크롤링을 위해 우리의 페이지 지정을 수정할 준비가 되었다. jQuery가 우리를 도와줄 것이다.

javascripts 디렉토리 안에 pagination.js.coffee 파일을 새로 만들자.

pagination.js.coffee

jQuery ->
  if $('#infinite-scrolling').size() > 0
    $(window).on 'scroll', ->
      more_posts_url = $('.pagination .next_page a').attr('href')
        if more_posts_url && $(window).scrollTop() > $(document).height() - $(window).height() - 60
            $('.pagination').html('<img src="/assets/ajax-loader.gif" alt="Loading..." title="Loading..." />')
            $.getScript more_posts_url
        return
      return

만약 페이지 지정이 페이지에 제공된다면 scroll 이벤트가 여기서 윈도우에 바인딩 된다. 사용자가 스크롤 하면, 다음 페이지에 대한 링크를 가져온다 - 방문하는 것은 Rails가 페이지로부터 레코드를 읽어오게 한다(여전히 우리는 이 동작을 위해 컨트롤러를 수정할 일이 남아있다)

그러면, URL이 제공되고 있고 사용자가 페이지 아래 마이너스 60px까지 스크롤하는지 체크하자. 이는 더 많은 포스트를 읽어오기 원하는 시점이다. 60px은 임의의 값이고 아마 케이스마다 그 값을 변경할 수 있을 것이다.

만약 이들 상태가 true이면 우리의 pagination은 ajaxload.info에서 자유롭게 다운로드 될 수 있는 "loading" GIF 이비지로 교체될 것이다. 마지막으로 해야할 것은 이전에 가져온 URL을 이용하여 실제로 비동기 요청을 수행하는 것이다. $.getScript 는 서버로부터 JS script를 로딩하고 그것을 실행할 것이다.

return 명령을 주목해라. 기본으로 CoffeeScript는 마지막 표현을 리턴할 것이다(동일한 컨셉이 루비에도 적용된다) 그러나 여기서 우리는 무언가를 리턴하는 jQuery 함수나 이벤트 핸들러를 원하지 않으므로 "return nothing"을 의미하는 return을 지정하였다.

PostController#index 메소드는 HTML과 JavaScript에 반응해야 한다. 이를 달성하기 위해 우리는 respond_to 를 사용할 것이다.

posts_controller.rb


@posts = Post.paginate(page: params[:page], per_page: 15).order('created_at DESC')
respond_to do |format|
  format.html
  format.js
end

마지막으로 할일은 JS에 응답했을 때 표현될 뷰를 생성하는 것이다.

index.js.erb


$('#my-posts').append('<%= j render @posts %>');
<% if @posts.next_page %>
  $('.pagination').replaceWith('<%= j will_paginate @posts %>');
<% else %>
  $(window).off('scroll');
  $('.pagination').remove();
<% end %>

우리는 #my-posts 블록에 더 많은 포스트들을 추가함으로써 더 많이 그리게 될 것이다. 그후, 페이지가 더 남아 있는지 체크하자. 만약 남아 있으면, 현재 pagination 블록(현 시점에는 "loading" 이미지를 포함하고 있다)을 새로운 pagination으로 교체한다. 남아 있지 않으면, 더이상 이벤트를 들을 지점이 없으므로 pagination 컨트롤을 제거하고 scroll 이벤트와 window를 바인딩 해제한다.

현재는, 무한 스크롤이 준비되었다. 사용자가 브라우저의 JavaScript를 disable 시켰더라도, bootstrap-will_paginate gem 덕분에 제공되는 몇몇 스타일을 가진 기본 pagination으로 표현될 것이다.

한가지 언급할 가치가 있는 것은 스크롤링이 scroll 이벤트의 작업량을 가중시킬 것이다. 만약 이 이벤트의 처리를 지연시키고자 한다면 Brian Grinstead가 작성한 BindWithDelay 오픈소스 라이브러리를 사용할 수 있다. 라이브러리를 사용하기 위해 단순히 소스를 다운로드 하고 그것을 프로젝트에 포함하기만 하면 된다. 그리고 나서, 소스에 다음과 같이 수정을 추가한다.

pagination.js.coffee


$(window).bindWithDelay 'scroll', ->
  # the code
, 100

이 소스는 100ms 만큼 이벤트 발사를 딜레이한다. index.js.erb 안의 $(window).off('scroll'); 코드는 여전히 event를 바인딩 해제할 것이다. 그러므로 그곳에는 수정을 필요로 하지 않는다.

이로써 문서의 첫 파트가 끝이났다. 다음 파트에서는 "Load more" 버튼에 대해 이야기 할 것이고 무한 스크롤을 사용할 때 발생하는 몇몇 문제점에 대해 얘기할 것이다.



출처 http://www.sitepoint.com/infinite-scrolling-rails-basics/

2015년 10월 11일 일요일

Ruby on Rails 서비스 개발을 위한 Gem 정리

1. 기본적으로 사용되는 gem들
- devise (https://github.com/plataformatec/devise) : 로그인, 회원가입 기능 개발을 도와줍니다.

- omniauth (https://github.com/intridea/omniauth) : twitter, facebook, google, openid, oauth등의 널리 사용되는 서비스의 ID로 로그인을 가능하게 합니다.

- cancan ( https://github.com/ryanb/cancan ) : railscast를 하는 ryanb라는 분이 만드신 gem인데, 사용자 계정에 따른 페이지 접근권한 관리를 해 줍니다. 사용자 테이블이 user, admin으로 갈라져 있는 경우에도 응용해서 사용할 수 있도록 유연합니다.

- mongoid( https://github.com/mongoid/mongoid ) : MongoDB를 사용하신다면 mysql2 gem대신에 이 gem을 써야 합니다. 하나의 프로젝트에 mysql과 mongoid 둘 다 동시에 혼용해서 사용하실 수도 있습니다. 저희 회사에서는 일부 데이터의 저장에 mongodb를 사용하고 있습니다.

- kaminari( https://github.com/amatsuda/kaminari ) : 목록 데이터의 페이지네이션을 해줍니다. 예전에는 will_paginate를 사용했었는데, 최근 kaminari가 더 좋아보입니다.

- resque ( https://github.com/defunkt/resque ) : web page의 request에 의존하지 않는 배치작업 처리를 관리해 줍니다. 전에는 delayed_job이라는 것을 썼었는데, resque가 성능면에서도 더 좋은 것 같고, GUI webpage interface도 있어서 좋아보입니다.

- paperclip ( https://github.com/thoughtbot/paperclip ) : 이미지 파일 관리를 도와줍니다. 자동으로 원하는 사이즈로 resize해서 저장합니다.

- meta_search ( https://github.com/ernie/meta_search ) : 데이터 검색, 정렬등을 쉽게 만들수 있게 도와줍니다. 주로 관리툴의 데이터 핸들링을 개발할 때 사용합니다.

- web-app-theme ( https://github.com/pilu/web-app-theme/ ) : 관리도구의 GUI를 쉽게 만들 수 있게 도와줍니다. CSS, javascript, HTML template를 생성해 주며, 다양한 theme을 지원합니다. 그리고, scaffold로 생성한 view도 여기 theme에 맞는 형식으로 overwrite해줘서 생산성을 높여 줍니다.

- activo ( https://github.com/dmfrancisco/activo ) : 위에서 소개한 web-app-theme과 쌍으로 같이 쓰이는데, 장점은 동일한 CSS요소를 쓰면서 formtastic이라는 form GUI helper형식의 CSS도 함께 제공합니다. 그리고 주관적인 생각이지만 조금 더 이쁩니다.

- formtastic ( https://github.com/justinfrench/formtastic ) : web form ui를 작은 코드로 생성할 수 있게 도와줍니다. 저는 아직 학습이 미숙해서 admin ui에만 활용하고 있습니다. 잘 쓴다면 사용자페이지의 form에도 적용하면 좋을 것 같습니다.

2. 선택적으로 사용할 수 있는 gem들
- awesome_nested_set ( https://github.com/collectiveidea/awesome_nested_set ) : 트리구조의 데이터 생성을 도와줍니다. 예를 들어 카테고리와 같은 Tree 자료주조 형태가 필요하면 이 gem을 사용합니다.

- acts-as-taggable-on ( https://github.com/mbleigh/acts-as-taggable-on ) : 모든 model을 대상으로 tagging을 할 수 있게 해줍니다. tag cloud 도 생성해 주고요.

- vestal_versions ( https://github.com/laserlemon/vestal_versions ) : 위키와 같이 데이터 변화의 revision을 관리해 줍니다. 특정 model에 적용해 두면 그 모델의 모든 변화는 추적가능합니다. 즉, 모든 변화를 log형태로 기록을 남길 수 있습니다.

- nested_form ( https://github.com/ryanb/nested_form ) : has_many, has_one 형태의 model간의 relation이 있는 경우, 하나의 form에서 입력을 받아야 할 경우 사용합니다.

- acts_as_commentable ( https://github.com/jackdempsey/acts_as_commentable ) : 모든 model을 대상으로 comment를 달 수 있게 합니다. 확장팩인 댓글의 댓글이 가능하게 하는  acts_as_commentable_with_threading이라는 gem도 있는데, 저도 많이 써보지 않아서 추천할 수 있는지는 아직 의문입니다.

- geocoder ( https://github.com/alexreisner/geocoder ) : 위도, 경도, 주소에 따라 근처 object등을 query해 준다던지 등의 위도, 경도, 주소 관련 관리를 해 줍니다. 지역정보 서비스를 하는데 사용하고 있습니다.

- twitter ( http://twitter.rubyforge.org/ ) : 트위터 연동을 쉽게 해 줍니다.

- mini_fb ( https://github.com/appoxy/mini_fb ) : 페이스북 연동을 쉽게 해 줍니다.

- memcache-client ( http://rubygems.org/gems/memcache-client ) : Rails가 아니여도 널리 사용되고 있는 memory cache시스템입니다. 성능을 위해서 memcached 사용은 필수죠.

- apn_on_rails ( https://github.com/PRX/apn_on_rails ) : apple push notification을 쉽게 할 수 있게 도와줍니다.

3. 그 밖의 gem들
- rqrcode ( http://whomwah.github.com/rqrcode/ ) : QR코드의 생성을 도와줍니다.

- encryptor ( http://github.com/shuber/encryptor ) : 암호화가 필요한 경우.

- stringex ( https://github.com/rsl/stringex ) : 루비 스트링 클래스의 확장기능을 제공합니다. 저는 이 중에서  “경기도”.to_url => “gyounggido” 과 같이 한글 음성 발음 대로 영문 URL패턴으로 변경되는 기능을 사용합니다.


그 외로 Rails 3.1에 기본으로 포함된 sass, coffee-script, uglifier, jquery-rails 등이 있음.

2015년 10월 5일 월요일

Ruby on Rails image uploads with CarrierWave and Cloudinary

When we set to develop Cloudinary’s Rails integration Gem, it was obvious to us that we’ll base it on CarrierWave. Here’s why.
Photos are a major part of your website. Your eCommerce solution will have multiple snapshots uploaded for each product. Your users might want to upload their photo to be used as their personal profile photo. What’s entailed when developing such a photo management pipeline, end-to-end?

  • You’ll need an HTML file upload form.
  • The server will need to manage the reception and processing of the uploaded image files.
  • Uploaded images should be stored on a safe storage with access for multiple application servers.
  • Model entities should keep references to uploaded images.
  • Uploaded images will need to be resized and cropped into different dimensions matching the graphics design of your web site.
  • The server will need to find and deliver the resized images to visitors of your site when displaying a page with the relevant model entity (e.g., display a thumbnail of the profile picture in a user profile page, etc.).
  • Allow overriding uploaded images with new ones when needed.
Cloudinary allows you to overcome this complexity in its entirety, but how does it work?

Over the years, we’ve had the pleasure of using some of RoR’s many excellent file upload solutions: CarrierWavePaperclipDragonflyattachment_fu and others. All-in-all, CarrierWave often proved a better fit for our needs:
  • Simple Model entity integration. Adding a single string ‘image’ attribute for referencing the uploaded image.
  • "Magic" model methods for uploading and remotely fetching images.
  • HTML file upload integration using a standard file tag and another hidden tag for maintaining the already uploaded "cached" version.
  • Straight-forward interface for creating derived image versions with different dimensions and formats. Image processing tools are nicely hidden behind the scenes.
  • Model methods for getting the public URLs of the images and their resized versions for HTML embedding.
  • Many others - see CarrierWave documentation page.
What we liked most is the fact the CarrierWave is very modular. You can easily switch your storage engine between a local file system, Cloud-based AWS S3, and more. You can switch the image processing module between RMagickMiniMagick and other tools. You can also use local file system in your dev env and switch to S3 storage in the production system.
 
When we developed Cloudinary and decided to provide a Ruby GEM for simple Rails integration, it was obvious that we’ll want to build on CarrierWave. Our users can still enjoy all benefits of CarrierWave mentioned above, but also enjoy the additional benefits that Cloudinary provides:
  • The storage engine is Cloudinary. All images uploaded through CarrierWave model methods are directly uploaded and stored in the cloud. 
  • All resized versions and image transformations are done in the cloud by Cloudinary: 
    • No need to install any image processing tools or Ruby GEMs. 
    • You can create the resized versions eagerly while uploading or lazily when users accesses the actual images. Save processing time and storage.
    • Change your desired image versions at any time and Cloudinary will just create them on the fly, no need to batch update all your images when the graphics design of your site changes.
  • All public image URLs returned by CarrierWave are Cloudinary URLs. This means they are automatically delivered through a global CDN with smart caching. Seamlessly enhancing the performance of your web application.
Some code samples:

class PictureUploader < CarrierWave::Uploader::Base

  include Cloudinary::CarrierWave
  
  version :standard do
    process :resize_to_fill => [100, 150, :north]
  end
  
  version :thumbnail do
    process :resize_to_fit => [50, 50]
  end     
    
end
class Post < ActiveRecord::Base
  ...
  mount_uploader :picture, PictureUploader
  ...
end
= form_for(:post) do |post_form|
  = post_form.hidden_field(:picture_cache)
  = post_form.file_field(:picture)
= image_tag(post.picture_url, :alt => post.short_name)

= image_tag(post.picture_url(:thumbnail), :width => 50, :height => 50)
We believe that for Ruby on Rails developers, the combination of Cloudinary with its CarrierWave-based gem, delivers a complete image management solution, with excellent model binding.
More details about about our CarrierWave plugin are available in our documentation:http://cloudinary.com/documentation/rails_integration#carrierwave_upload
What do you think about our solution? any suggestions or improvement ideas?
UPDATE: We've published another post about additional advanced image transformations in the cloud with CarrierWave & Cloudinary.

2015년 10월 4일 일요일

Linux에서 find로 문자열 찾기

문자열찾기 방법 1 - 영어만 주로 가능 
# grep -rw "찾는문자열" ./

문자열찾기 방법 2 - 대/소문자 구분 안하고 검색
# grep -i -l "찾는문자열" * -r 2> /dev/null

문자열찾기 방법 3 - 한글, 영어 모두 가능
# find . -exec grep -l "찾는문자열" {} \; 2>/dev/null

문자열찾기 방법 4 - 한글,영어, 대소문자 안가리고 검색
# find . -exec grep -i -l "찾을문자열" {} \; 2>/dev/null

문자열찾은 후 치환
# find . -exec perl -pi -e 's/찾을문자열/바꿀문자열/g' {} \; 2>/dev/null

파일명 찾기
# find / -name 파일명 -type f 
파일명 찾기(대소문자 구별없음)
# find / -iname 파일명 -type f 
디렉토리 찾기
# find / -name 파일명 -type d 
디렉토리 찾기(대소문자 구별없음)
# find / -iname 파일명 -type d

특정 사용자 소유의 모든 파일을 찾을때는?
# find / -user "사용자 ID" -print

두세가지 문자열을 동시에 찾아야 할때는 egrep을 쓰면 아주 편합니다.
예를 들어
만약 그냥 grep으로 문자열1,2 를 찾으려면
ps -ef | grep 문자열1; ps -ef | grep 문자열2 와 같이 해야하는것을 egrep를 이용하면

ps -ef | grep '문자열1|문자열2'
와 같이 간단해집니다.

# egrep '(pattern1|pattern2|pattern3)' file.txt

2015년 10월 2일 금요일

마이그레이션을 사용해 컬럼 추가하기

기 생성된 테이블에 새로운 컬럼을 추가하고자 한다.

추가하는 컬럼 데이터 타입이 기본 string인 경우

1. $ bin/rails g migration add_컬럼명_to_테이블명

2. $ rake db:migrate

위의 이름으로 마이그레이션 파일을 생성하면 자동으로 change 메소드 내용이 채워지므로 마이그레이션 파일을 수정할 필요가 없다.

class Add컬럼명To테이블명 < ActiveRecord::Migration
  def change
    add_column :테이블명, :컬럼명, :데이터타입
  end
end





2015년 10월 1일 목요일

마이그레이션을 사용해 컬럼속성 변경하기

테이블에 생성된 기존 column의 default 속성을 변경하고자 하는 경우 아래와 같이 실행한다.

1. $ bin/rails g migration ChangeColumnName

ChangeColumnName은 마이그레이션 이름이며 적절하게 다른 이름으로 변경할 수 있다.

2. 생성된 db/migrate/<timestamp>_change_column_name.rb 파일을 수정한다.

class ChangeColumnName < ActiveRecord::Migration
def change
change_column_default :table_name, :column_name, '기본값'
end
end

3. $ rake db:migrate
change_column_default :xxx

[참고] 마이크레이션의 change 메소드에서 지원하는 정의들
  • add_column
  • add_index
  • add_reference
  • add_timestamps
  • add_foreign_key
  • create_table
  • create_join_table
  • drop_table (반드시 블럭을 사용할 것)
  • drop_join_table (반드시 블럭을 사용할 것)
  • remove_timestamps
  • rename_column
  • rename_index
  • remove_reference
  • rename_table