0

ruby/rails/hobo の最新バージョンに移植する必要がある、数年前に誰かが書いた ruby​​/rails/hobo システムがあります。ruby は下位互換性を気にしていないようです。そのため、古いアプリで動作していたコードは動作しなくなりました。

古いアプリでは、observation.rb モデル ファイルに次のように記述されています。

belongs_to :survey
has_one :site, :through => :survey

def create_permitted?
  acting_user == self.survey.contact or acting_user.administrator?
end

survey.rb モデル ファイルは次のとおりです。

belongs_to :contact, :class_name => 'User', :creator => true

残念ながら、observation.rb のコードは新しい ruby​​/rails/hobo では機能せず、次のエラーが表示されます。

NoMethodError in Observations#index

Showing controller: observations; dryml-tag: index-page where line #1 raised:

undefined method `contact' for nil:NilClass
Extracted source (around line #1):

0
Rails.root: /home/simon/ruby/frogwatch2

Application Trace | Framework Trace | Full Trace
app/models/observation.rb:48:in `create_permitted?'

「create_permitted」メソッドをどのように変更する必要がありますか? ruby/rails/hobo のドキュメントは非常にひどいものであることがわかりました (これはフリー ソフトウェアであるため、十分に公平です)。また、Googleでこれを検索する方法さえわかりません(私は何日も試してきました)。

助けてください!:)

4

3 に答える 3

2

Rails に関するドキュメントのさまざまな見解とは別にcontact、この場合は存在しないアンケートを呼び出しているため、呼び出しが発生しますnil.contact

別の方法として、 を呼び出す前に調査の存在を確認することもできますcontact。たとえば、このような方法です。

def create_permitted?
  acting_user == (survey && survey.contact) or acting_user.administrator?
end
于 2012-12-10T16:10:54.417 に答える
1

他の2人が言ったことをエコーし​​ます。参照しようとしている調査はnilであり、とnil呼ばれるメソッドがありませんcontact。少し異なるソリューションを提供します。

def create_permitted?
  acting_user == survey.try(:contact) or acting_user.administrator?
end

#tryメソッドはとに存在nilしますsurvey。基本的に、メソッド呼び出しをでラップしrescueます。概念的には、次のようになります。

def try(method_name, *args)
  self.send(method_name, args) rescue nil
end

これにより、関係が存在しない可能性のある条件をキャッチするために作成する必要のあるコードの量が減り、NoMethodError例外が防止される場合があります。

#tryのRailsコア拡張機能の一部ですObject。実際には、への呼び出しから発生する例外Object#tryは通常どおりに発生するため、上記のようには機能しません。代わりに、Objectを呼び出すことによって拡張しsendます。NilClassを返すことで拡張されるnilため、にメソッドを送信しようとせずNilClass、を防ぎますNoMethodError。tadmanがコメントで指摘しているように、キャッチオール例外ハンドラーは通常はお勧めできません。

https://github.com/rails/rails/blob/6ef9fda1a39f45e2d18aba4881f60a19589a2c77/activesupport/lib/active_support/core_ext/object/try.rb

アップデート

より良い解決策、そして私が忘れていた解決策は、を使用することdelegateです。

例えば:

class User < ActiveRecord::Base
  delegate :contact, to: :survey, prefix: true, allow_nil: true
end

次に、を呼び出しuser.survey_contact、調査がである場合は正常に失敗しnilます。

于 2012-12-10T16:20:44.657 に答える
1

参照列 ( ) に無効な参照 IDsurvey_idが含まれている可能性があるため、エラーが発生しています。null

nullまたは無効な参照が許可されている場合は、それを処理するようにコードを変更します

( self.survey and acting_user == self.survey.contact ) or acting_user.administrator?
于 2012-12-10T16:09:34.540 に答える