당신이 모를 수 있는 Rails 트릭

11254 단어 railsruby
나는 많은 새로운 Rails 개발자가 프레임워크의 기본 사항과 씨름하는 것을 봅니다. 나는 한동안 Rails를 사용해 왔으며 그 과정에서 몇 가지 요령을 배웠습니다. 이 트릭을 여러분과 공유해야겠다고 생각했습니다.

하나의 작업, 다양한 방법



때로는 하나의 작업을 갖는 것이 유용하지만 getpost(또는 다른 작업) 모두에서 작동하도록 합니다. 예를 들어 사용자가 보고서를 생성할 수 있는 페이지가 있는 경우입니다. 사용자는 범위에서 일부 날짜를 선택한 다음 버튼을 클릭하여 보고서를 생성해야 합니다. 그리고 내가 자주 보는 것은 사람들이 컨트롤러 내부에 두 가지 작업을 생성한다는 것입니다.

# app/controllers/reports_controller.rb
class ReportsController < ApplicationController
  def super_report
    # render form
  end

  def super_report_post
    # generate report
  end
end

# config/routes.rb
get 'reports/super_report', to: 'reports#super_report'
post 'reports/super_report', to: 'reports#super_report_post'


하지만 더 좋은 방법이 있습니다. 원하는 스타일을 선택하세요:

# config/routes.rb

# Option one
get 'reports/super_report', to: 'reports#super_report'
post 'reports/super_report', to: 'reports#super_report'

# Option two
match 'reports/super_report', to: 'reports#super_report', via: [:get, :post]


그리고 컨트롤러에서:

# app/controllers/reports_controller.rb
class ReportsController < ApplicationController
  def super_report
    if request.post?
      # generate report
    else
      # render form
    end
  end
end


이제 로직을 두 개의 작업으로 분할하지 않지만 getpost 모두에서 작동하는 하나의 작업이 있습니다. 더 멋지고 읽기 쉽고 유지하기 쉬워 보입니다.

네임스페이스



네임스페이스는 컨트롤러와 경로를 그룹화하는 방법입니다. 컨트롤러가 많고 그룹화하려는 경우에 유용합니다. 예를 들어 PostsController , Admin::UsersControllerAdmin::PostsController 컨트롤러가 있습니다. 관리자에 대해 다른 보기를 원하고 이에 대한 인증을 원합니다.

# config/routes.rb
resources :posts

namespace :admin do
  resources :users
  resources :posts
end


이제 URLAdmin::UsersController을 사용하여 /admin/users에 액세스하고 URLAdmin::PostsController을 사용하여 /admin/posts에 액세스할 수 있습니다. 또한 컨트롤러 내에서 네임스페이스를 사용해야 합니다.

# app/controllers/admin/users_controller.rb
class Admin::BaseController < ApplicationController
  layout "admin" # special view layout for admins

  before_action :authenticate_admin!
end

class Admin::UsersController < Admin::BaseController
  # ... Only admin can work with it
end

class Admin::PostsController < Admin::BaseController
  # ... Only admin can work with it
end



# Views structure
app/views/layouts/admin.html.erb
app/views/posts/
app/views/admin/posts/
app/views/admin/users/


범위가 지정된 연결


UserPost 의 두 가지 모델이 있다고 가정해 보겠습니다. 그리고 우리는 사용자에 대한 모든 게시물을 얻고 싶습니다. 우리는 할 수있어:

class User < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :user
end

user = User.first
user.posts


하지만 게시된 사용자의 게시물을 포함하고 싶지 않다면 어떻게 해야 할까요? 나는 종종 이렇게 하는 사람들을 봅니다.

class User < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :user

  scope :published, -> { where(published: true) }
end

user = User.first
user.posts.published


이것은 괜찮지만 쿼리에 published 범위를 추가하는 것을 잊을 수 있습니다. 그런 다음 게시되지 않은 모든 게시물을 받게 됩니다. 그리고 이것은 당신이 원하는 것이 아닙니다. 어떤 사람들은 이것을 위해 default_scope를 사용하지만 좋은 생각은 아닙니다. 그래서 우리는 무엇을 할 수 있습니까? scope를 연관하여 사용할 수 있습니다.

class User < ActiveRecord::Base
  has_many :posts, -> { published }
  has_many :not_published_posts, -> { not_published }
end

class Post < ActiveRecord::Base
  belongs_to :user

  scope :published, -> { where(published: true) }
  scope :not_published, -> { where(published: false) }
end

user = User.first
user.posts # only published posts here


마이그레이션은 스키마 구축만을 위한 것이 아닙니다.



마이그레이션을 사용하여 일부 데이터를 데이터베이스에 추가할 수 있습니다. 예를 들어 모델User이 있고 데이터베이스에 대한 ID가 -1인 관리자를 생성하려고 합니다. 따라서 어디에서나 어떤 환경에서든 그러한 사용자가 존재하는지 확인하고 싶습니다. 다음과 같이 할 수 있습니다.

class AddAdmin < ActiveRecord::Migration
  ADMIN = User.find_by(id: -1)

  def up
    User.create(name: 'Admin', id: -1, admin: true) unless ADMIN
  end

  def down
    ADMIN.destroy if ADMIN
  end
end


마무리



이 트릭이 유용하기를 바랍니다. 다른 멋진 예시가 있다면 댓글로 공유해주세요.

추신 표지 이미지는 DALL·E 2를 사용하여 생성됩니다.

좋은 웹페이지 즐겨찾기