私はチームツリーハウスコースに従っています。リファクタリングされていることの 1 つは、投稿されるステータスの user_id を、現在ログインしているユーザーのみに制限する機能です。投稿するにはログインする必要があるというフィルターを既に確立しているため、ここで実行しようとしているのは、ユーザーが別のユーザーとしてステータスを投稿できないようにすることだけです。
ユーザーhas_many :statuses
これは、コントローラーで Statuses#create メソッドがどのように見えるかです
def create
@status = Status.new(params[:status])
respond_to do |format|
if @status.save
format.html { redirect_to @status, notice: 'Status was successfully created.' }
format.json { render json: @status, status: :created, location: @status }
else
format.html { render action: "new" }
format.json { render json: @status.errors, status: :unprocessable_entity }
end
end
end
私たちが変えていることは、@status = Status.new(params[:status])
現在、User モデルに Devise を使用しているため、現在のユーザーは次のように表されます。current_user
次の変更が作成されます。@status = current_user.statuses.new(params[:status])
この声明は私を混乱させます
ここで何が起こっているのかを理解しようとしました。
以下は、Rails コンソールを使用したプロセスの調査です。
irb(main):003:0> User.first.statuses
User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1
Status Load (0.1ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."user_id" = 2
=> [#<Status id: 2, content: "this is a test status", created_at: "2013-07-23 20:53:35", updated_at: "2013-07-23 20:53:35", user_id: 2>, #<Status id: 3, content: "test2", created_at: "2013-07-23 21:34:59", updated_at: "2013-07-23 21:34:59", user_id: 2>]
irb(main):004:0> User.first.statuses.class
User Load (0.6ms) SELECT "users".* FROM "users" LIMIT 1
Status Load (0.3ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."user_id" = 2
=> Array
irb(main):005:0> User.first.statuses.new.class
User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1
=> Status(id: integer, content: text, created_at: datetime, updated_at: datetime, user_id: integer)
irb(main):006:0> Array.new
=> []
irb(main):007:0> Array.new.class
=> Array
irb(main):008:0>
User.first.statuses から返されたオブジェクトのクラス (予想どおり) が配列であることがわかったのに、配列で呼び出された .new のクラスが新しいステータスを生成したのはなぜですか。これはどのように/なぜ機能するのですか? Array.new を呼び出すと、配列が取得されます。配列オブジェクトに対して new を呼び出していませんか?