5

私は、あなたの多くが睡眠中に避けることができると確信している問題を解決する助けを得たいと思っています.

私は、habtm 関係にある 2 つのモデルを持っています。1 つのパッケージに複数の場所を含めることができ、1 つの場所に複数のパッケージを含めることができます。ロケーション モデルが検証に失敗した場合 (ロケーション アドレスが空の場合など)、ActiveRecord:RecordInvalid 例外が発生します。package.save を呼び出すと、Rails が自動的に save! を呼び出すため、このエラーが発生することを理解しています。場所の関連付けについて。

エラーを回避する方法、または少なくともエラーを救う方法がわかりません。問題を解決する方法とRailsのベストプラクティスの両方について、何か良いアドバイスはありますか?

コードは次のとおりです。

def create
    @package = current_user.package.build(params[:package])
    package_location
    if @package.save
      flash[:success] = "Package created!"
      redirect_to root_path
    else        
      render 'pages/home'
    end
  end

  def package_location
    gps_processing if !session[:gps_aware]
    @package.locations.build(:address => session[:address])
  end

  def gps_processing
    session[:address] = [params[:story][:street_address], params[:story][:city], params[:story][:state], params[:story][:country]].compact.join(', ')
  end

class Package< ActiveRecord::Base

  belongs_to :user
  has_and_belongs_to_many :locations

  validates         :content,   :presence   => true, 
                    :length     => {:maximum => 140}
  validates      :user_id,    :presence => true

  default_scope :order => 'package.created_at DESC'

end

class Location < ActiveRecord::Base

  attr_accessible :lng, :lat, :address

  validates     :lng,       :presence   => true
  validates     :lat,       :presence   => true
  validates     :address,   :presence   => true

  geocoded_by :full_street_address, :latitude => :lat, :longitude => :lng  

  before_validation :geocode

  has_and_belongs_to_many :packages

  def full_street_address
    address
  end
end

` 前もって助けてくれてありがとう!

4

3 に答える 3

24

選択した回答は正確ではありません。ドキュメントhereによると、この例外をレスキューする簡単な方法があります。

begin
  complex_operation_that_calls_save!_internally
rescue ActiveRecord::RecordInvalid => invalid
  puts invalid.record.errors
end

エラーのメッセージ インスタンス変数にアクセスして、関連するフィールドとエラー メッセージを取得できます。

于 2014-10-12T05:37:07.810 に答える
2

私の頭の上からいくつかのアイデア:

使用@package.save!とレスキュー ブロック:

def create
  @package = current_user.package.build(params[:package])
  package_location
  @package.save!
  flash[:success] = "Package created!"
  redirect_to root_path
rescue      
  render 'pages/home'
end

Package モデルでvalidates_associatedを使用し、有効な場合にのみ保存します。

def create
  @package = current_user.package.build(params[:package])
  package_location

  # You might be able to just use if(@package.save), but I'm not positive.
  if(@package.valid?)
    @package.save!
    flash[:success] = "Package created!"
    redirect_to root_path
  else      
    render 'pages/home'
  end
end

Rubyで作業しているので、他にもいくつかの方法があると思います...

それが役立つことを願っています!

于 2011-03-24T23:28:26.310 に答える
0

これは、保存が失敗した理由についてユーザーに適切なフィードバックを提供しながら、問題を解決するために使用したコードです。私の洗練されていない ruby​​ コードを許してください。

1 つの小さな問題が残っています。. . パッケージと場所の両方が検証に失敗した場合、リロード時に場所のエラー メッセージのみが表示されます。その後、ユーザーが場所のエラーを修正し、パッケージのエラーを修正しない場合、パッケージのエラー メッセージが表示されます。最初のリロード時にすべてのエラーを表示する方法に取り組んでいます

  def create
    @package= current_user.package.build(params[:package])
    if package_location && @package.save
        flash[:success] = "Package created!"
        redirect_to root_path
      else
        render 'pages/home'
    end
  end

 def package_location
   gps_processing if !session[:gps_aware]
   location = @package.locations.build(:address => session[:address])
   if !location.valid?
     @package.errors.add(:address, "You have entered an invalid address") 
     return false
   else
      return true
   end
 end

 def gps_processing
   session[:address] = [params[:story][:street_address], params[:story][:city], 
          params[:story][:state], params[:story][:country]].compact.join(', ')
 end
于 2011-03-26T21:59:23.397 に答える