0

単純なhas_manybelongs_to関係があり、belongs_toモデルのビューの親オブジェクトを含めたいのですが、ある程度の成功を収めていますが、より適切に機能させたいと考えています。

class Submission < ActiveRecord::Base
  belongs_to :user
  belongs_to :contest
end
class Contest < ActiveRecord::Base
  belongs_to :user
  has_many :submissions, :dependent => :destroy
end

うまくいく場合は、contest_idを次のURLに配置して提出物に渡します。

   <%= link_to 'Submit Contest Entry', new_submission_path(:contest_id => @contest.id), 
                            :class => 'btn btn-primary btn-large mleft10' %>

そのため、hidden_​​fieldと組み合わせると:

 <%= f.hidden_field :contest_id %>

そして、コントローラーのfind_contestメソッド(before_filterで呼び出されます):

def find_contest
  #the next line is giving the error (line 76)
  @contest = Contest.find(params[:submission][:contest_id])
end

送信/新規で機能するようにしますが、showやindexでアクセスする場合のように、複数のページで機能する検索結果をコントローラーに追加するにはどうすればよいですか。現在、エラーが発生します:

Started GET "/submissions?contest_id=5" for 127.0.0.1 at 2012-12-01 16:01:45 -0800
Processing by SubmissionsController#index as HTML
  Parameters: {"contest_id"=>"5"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY users.created_at DESC LIMIT 1
Completed 500 Internal Server Error in 37ms

NoMethodError (undefined method `[]' for nil:NilClass):
  app/controllers/submissions_controller.rb:76:in `find_contest'

[編集]提出物の表示アクションの追加:

before_filter :find_contest, :except => [:index, :show, :edit, :update, :destroy]

def find_contest
  @contest = Contest.find(params[:submission][:contest_id])
end

def show
  contest_id = @submission.contest_id
  @submission = @commentable = Submission.find(params[:id])
  @comments = @commentable.comments.order(:created_at).reverse
  respond_to do |format|
    format.html  # show.html.erb
    format.json  { render :json => @submission }
  end
end
4

2 に答える 2

0

これがこの質問への答えですが、私はインデックスとショーの両方に2行を使用しましたが、おそらく1つにリファクタリングできます(編集注:Pablo89はショーのリファクタリングを提案しましたが、これは含まれていますが、インデックスはまだ2行です)

ただし、どちらの場合も、特に初心者にとっては、2つの行が非常に重要です。その理由は、次のとおりです。

parent_id(contest_id)を関連するビュー(showsubmission)に渡すために、paramsのsubmission_idを使用して@submission(@associated)を定義しました(コメントは別の目的であり、無視できます)。

@submission = @commentable = Submission.find(params[:id])

この場合、パラメータはWebサイトのアドレスにあります。

http://localhost:3000/submissions/41

41はsubmission_idです。それは明らかです。

Railsは、ブラウザウィンドウにあるページのアドレスを使用して、インスタンス値を割り当てます。Railsは非常に多くのことを自動的に行うため、これ以前はRailsがどこでパラメーターを見つけていたのかわかりませんでした。paramsはWebページのアドレスです。DOH!

次に、belongs_toアソシエーションの一部として必要な@submissionのcontest_idキーを使用して、contest_idを割り当て、findを使用して@contestにアクセスしました。

contest_id = @submission.contest_id
@contest = Contest.find(contest_id)

Pablo89が指摘しているように、レールの結合力により、2本の線を1本に減らすことができます。

@contest = @submission.contest

インデックスには@submissionがないので、contest/showとsubmissions/showの2つの場所にあるlink_tothatページを介してcontest_idをこのページに渡します。

<%= link_to 'Browse All Submissions', submissions_path(:contest_id => @contest.id), :class => 'btn btn-mini pull-right' %>

リンクをクリックすると、送信/インデックスに移動し、次のアドレスに結果が表示されます。

http://localhost:3000/submissions?contest_id=4

(:contest_id => @ contest.id)アドレスに?contest_id = 4を追加して、「params」を介して送信コントローラーからアクセスできるようにします。

私のような初心者にとって、これはパラメータの理解を深めるための重要な方法です。ページのアドレスは、Railsが@submissionや@contestなどからインスタンス変数を割り当てている場所だからです。

ネストされたルートは次のようになります。

コンテスト/5/サブミッション/41

ネストされたルートを使用している場合、コンテストと送信の値はアドレスにあり、使用されるのを待っています。アドレスは「params」とも呼ばれます(私のような頭蓋骨が厚い他の学習者に伝えるために繰り返します)が、ネストされたルートを使用していない場合は、親IDを別の方法で渡す必要があります。上記の例のlink_toにそれを。

そこから、?contest_id = 4にアクセスするために、提出物のインデックスアクションに次のように入力します。

contest_id = params[:contest_id]
@contest = Contest.find(contest_id)

これは私にとって少し画期的なことです。これまで、パラメータが何であるか、またはどのように機能するかを知らなかったので、それが機能しただけでした。

この基本的な概念を理解することで、ほとんどの経験豊富な開発者は、言及しようとは思わないことをよく知っているので、コントローラーについてさらに深く理解できます。

私はここで中継したすべての点で正しいかもしれないし、そうでないかもしれませんが、これが他の初心者にとって役立つことを願っています。私は今、物事を理解する能力に非常に自信を持っています。これ以前は、paramsで行っていたことの多くは、基本的な理解がなくても機能するまで、さまざまな方法を試していました。とてもシンプルなので、今は笑わせてくれます。paramsという言葉は、どこにいても任意のパラメーターを参照できるという点で、やや手ごわいものだと思います。

Railsがこれらの値を割り当てるために使用しているのはWebアドレスパラメータです。わお!なんと画期的な...

于 2012-12-02T22:51:44.940 に答える
0

コントローラーSubmissionsControllerのアクションインデックスにアクセスしています。アクションインデックス内でメソッドfind_contestを呼び出していると仮定します。エラーは、メソッドfind_contest内でparams[:submission][:contest_id]の値を取得しようとしているが、そのようなパラメーターが存在しないためです。取得しているパラメーターはparams[:contest_id]です。

多くのアクションを通じて同じメソッドを管理するためにできることは、次のようにメソッドを変更してパラメーターを渡すことです。

def find_contest(contest_id)
  @contest = Contest.find(contest_id)
end

def index
  find_contest(params[:contest_id])
  #some other code...
end

ただし、 before_filterのようなものを使用している場合は、params [:contest_id].nil ? nil でない場合はそれを使用し、そうでない場合はparams[:submission][:contest_id]を使用します。

于 2012-12-02T20:20:39.870 に答える