문제

저는 매우 기본적인 장바구니 시스템을 연구하고 있습니다.

테이블이 있어요 items 열이 있는 것 price 유형의 integer.

유로와 센트가 모두 포함된 가격에 대한 내 보기에 가격 값을 표시하는 데 문제가 있습니다.Rails 프레임워크에서 통화를 처리하는 것과 관련하여 제가 뭔가 분명한 것을 놓치고 있는 걸까요?

도움이 되었습니까?

해결책

아마 사용하고 싶을 것입니다 DECIMAL 데이터베이스를 입력하십시오. 마이그레이션에서 다음과 같은 작업을 수행하십시오.

# precision is the total number of digits
# scale is the number of digits to the right of the decimal point
add_column :items, :price, :decimal, :precision => 8, :scale => 2

레일에서 :decimal 유형은 다음과 같이 반환됩니다 BigDecimal, 가격 계산에 적합합니다.

정수 사용을 고집하면 수동으로 BigDecimal어디에서나, 아마도 고통이 될 것입니다.

MCL이 지적한 바와 같이 가격을 인쇄하려면 사용합니다.

number_to_currency(price, :unit => "€")
#=> €1,234.01

다른 팁

다음은 다음을 활용하는 훌륭하고 간단한 접근 방식입니다. composed_of (ValueObject 패턴을 사용하는 ActiveRecord의 일부) 및 Money gem

너는 필요할거야

  • 그만큼 돈 보석 (버전 4.1.0)
  • 예를 들어 모델 Product
  • integer 예를 들어 모델(및 데이터베이스)의 열 :price

이것을 당신의 편지에 쓰세요 product.rb 파일:

class Product > ActiveRecord::Base

  composed_of :price,
              :class_name => 'Money',
              :mapping => %w(price cents),
              :converter => Proc.new { |value| Money.new(value) }
  # ...

당신이 얻을 것:

  • 추가 변경 없이 모든 양식에는 달러와 센트가 표시되지만 내부 표현은 여전히 ​​센트에 불과합니다.양식은 "$12,034.95"와 같은 값을 허용하고 이를 변환합니다.모델에 핸들러나 속성을 추가하거나 뷰에 도우미를 추가할 필요가 없습니다.
  • product.price = "$12.00" 자동으로 Money 클래스로 변환됩니다.
  • product.price.to_s 10진수 형식의 숫자("1234.00")를 표시합니다.
  • product.price.format 통화에 대해 올바른 형식의 문자열을 표시합니다.
  • 센트를 보내야 하는 경우(페니를 원하는 결제 게이트웨이로), product.price.cents.to_s
  • 무료 환율 변환

통화를 처리하는 일반적인 방법은 10진수 형식을 사용하는 것입니다.다음은 "Rails를 사용한 Agile Web Development"의 간단한 예입니다.

add_column :products, :price, :decimal, :precision => 8, :scale => 2 

이를 통해 -999,999.99에서 999,999.99까지 가격을 처리할 수 있습니다.
다음과 같은 항목에 유효성 검사를 포함할 수도 있습니다.

def validate 
  errors.add(:price, "should be at least 0.01") if price.nil? || price < 0.01 
end 

당신의 가치관을 온전하게 점검하십시오.

사용 머니 레일 보석. 그것은 당신의 모델에서 돈과 통화를 잘 처리하고 또한 당신의 가격을 포맷 할 수있는 많은 도우미를 가지고 있습니다.

Postgres를 사용하는 경우 (그리고 2017 년 이후로) :money 열 유형 A 시도.

add_column :products, :price, :money, default: 0

사용 가상 속성 (수정 된 (유료) RAILSCAST에 대한 링크) 정수 열에 price_in_cents를 저장하고 제품 모델에 가상 속성 price_in_dollars를 getter and setter로 추가 할 수 있습니다.

# Add a price_in_cents integer column
$ rails g migration add_price_in_cents_to_products price_in_cents:integer

# Use virtual attributes in your Product model
# app/models/product.rb

def price_in_dollars
  price_in_cents.to_d/100 if price_in_cents
end

def price_in_dollars=(dollars)
  self.price_in_cents = dollars.to_d*100 if dollars.present?
end

원천: RailScasts #016 : 가상 속성: 가상 속성은 데이터베이스에 직접 매핑되지 않는 양식 필드를 추가하는 깨끗한 방법입니다. 여기서 나는 검증, 협회 등을 처리하는 방법을 보여줍니다.

분명히 정수.

그리고 Bigdecimal은 기술적으로 존재하지만 1.5 루비에서 여전히 순수한 부유물을 줄 것입니다.

누군가가 속편을 사용하는 경우 마이그레이션은 다음과 같습니다.

add_column :products, :price, "decimal(8,2)"

어떻게 든 속편이 무시됩니다 : 정밀도와 : 스케일

(속편 버전 : 속편 (3.39.0, 3.38.0))

이 방법으로 사용하고 있습니다.

number_to_currency(amount, unit: '€', precision: 2, format: "%u %n")

물론 통화 기호, 정밀, 형식 등은 각 통화에 따라 다릅니다.

몇 가지 옵션을 전달할 수 있습니다 number_to_currency (표준 레일 4 도우미보기) :

number_to_currency(12.0, :precision => 2)
# => "$12.00"

게시자와 같이 Dylan Markow

나의 기본 API는 모두 돈을 대표하기 위해 센트를 사용하는 것이었고, 나는 그것을 바꾸고 싶지 않았습니다. 나는 많은 돈으로 일하지 않았다. 그래서 나는 이것을 도우미 방법에 넣었습니다.

sprintf("%03d", amount).insert(-3, ".")

정수를 최소 3 자리 숫자 (필요한 경우 선행 제로 추가)로 문자열로 변환 한 다음 마지막 두 자리 숫자 전에 소수점을 삽입합니다. Float. 여기에서 사용 사례에 적합한 통화 기호를 추가 할 수 있습니다.

이것의 분명히 빠르고 더럽지 만 때로는 괜찮습니다!

Ruby & Rails에 대한 간단한 코드

<%= number_to_currency(1234567890.50) %>

OUT PUT => $1,234,567,890.50

ROR 개발에서 야심 찬 주니어/초보자에 대한 약간의 업데이트와 응집력은 확실히 설명을 위해 여기에 올 것입니다.

돈으로 일합니다

사용 :decimal @molf가 제안한대로 DB에 돈을 저장하기 위해 (그리고 돈으로 일할 때 회사가 황금 표준으로 사용하는 것).

# precision is the total number of digits
# scale is the number of digits to the right of the decimal point
add_column :items, :price, :decimal, precision: 8, scale: 2

몇 가지 요점 :

  • :decimal 사용될 것입니다 BigDecimal 많은 문제가 해결됩니다.

  • precision 그리고 scale 대표하는 것에 따라 조정해야합니다.

    • 지불금을 받고 보내는 일을하는 경우 precision: 8 그리고 scale: 2 당신을 준다 999,999.99 가장 많은 양으로, 90%의 경우에 적합합니다.

    • 부동산 또는 희귀 자동차의 가치를 대표 해야하는 경우 더 높은 것을 사용해야합니다. precision.

    • 좌표 (경도 및 위도)로 작업하면 반드시 더 높아야합니다. scale.

마이그레이션을 생성하는 방법

위의 내용으로 마이그레이션을 생성하려면 터미널에서 실행하십시오.

bin/rails g migration AddPriceToItems price:decimal{8-2}

또는

bin/rails g migration AddPriceToItems 'price:decimal{5,2}'

이것에 설명 된 바와 같이 블로그 게시하다.

통화 형식

키스 추가 라이브러리는 작별이며 내장 된 도우미를 사용합니다. 사용 number_to_currency @molf와 @facundofarias가 제안한 것처럼.

놀기 위해 number_to_currency Rails Console의 도우미, 전화를 보내십시오. ActiveSupport'에스 NumberHelper 도우미에 액세스하기 위해 클래스.

예를 들어:

ActiveSupport::NumberHelper.number_to_currency(2_500_000.61, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")

다음 출력을 제공합니다

2500000,61€

다른 사람을 확인하십시오 options숫자 _to_currency 돕는 사람.

그것을 어디에 두어야하는지

애플리케이션 도우미에 넣고 모든 금액에 대해보기 내에서 사용할 수 있습니다.

module ApplicationHelper    
  def format_currency(amount)
    number_to_currency(amount, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
  end
end

또는 당신은 그것을 넣을 수 있습니다 Item 인스턴스 방법으로 모델링하고 가격 (보기 또는 도우미)을 포맷 해야하는 곳에 호출하십시오.

class Item < ActiveRecord::Base
  def format_price
    number_to_currency(price, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
  end
end

그리고, 내가 어떻게 사용하는지 예 number_to_currency Contrroler 내부 (참조 negative_format 옵션, 환불을 나타내는 데 사용됨)

def refund_information
  amount_formatted = 
    ActionController::Base.helpers.number_to_currency(@refund.amount, negative_format: '(%u%n)')
  {
    # ...
    amount_formatted: amount_formatted,
    # ...
  }
end
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top