1

ビュー内の私のコードは次のとおりです: show.html.erb

<ul>
<% @bullets.each do |r| %>
    <li><%= r.content %></li>
<% end %>
</ul>

コントローラー内のコードは次のとおりです: users_controller.rb

if cookies[:bullets].nil?
  @bullets = Bullet.all.shuffle.first(4)
  cookies[:bullets] = @bullets.collect(&:id)
else
 @bullets = []
 cookies[:bullets].each do |id|
   @bullets << Bullet.find(id)
 end
end

これは nil:NilClass に対して未定義のメソッド 'each' を返します

<% @bullets.each do |r| %>

なぜこれが行われるのか、また、「弾丸」という名前のデータベース (sqlite3) テーブル (列はコンテンツ) から 4 つのランダムな固定された箇条書きコンテンツを投稿するように修正するにはどうすればよいかを知りたいです。

編集:これはコントローラー全体です:

class StudentsController < ApplicationController
    #GET /
    def index
      @students = Student.all 

      respond_to do |format|
        format.html # index.html.erb
        format.json { render json: @students }
        end  
    end 

    #GET /new
    def new 
      @student = Student.new
    end 

    #POST
    def create
      @student = Student.new(params[:student])
          if @student.save
        render :file => 'app/views/success'
      else 
        render :file => 'app/views/students/fail'
      end  
        end

    #GET /students/{:id}
    def show 
       @student = Student.find_by_url(params[:id])

           respond_to do |format|
         format.html # show.html.erb
         format.json { render json: @student } 
           end  
    end

    #BULLETS Randomizing /students/new.html.erb
    if cookies[:bullets].nil?
      @bullets = Bullet.all.shuffle.first(4)
      cookies[:bullets] = @bullets.collect(&:id)
    else
     @bullets = []
     cookies[:bullets].each do |id|
       @bullets << Bullet.find(id)
     end
    end

    #GET /students/1/edit
    def edit 
        @student = Student.find_by_url(params[:id])
    end 

    def update
      @student = Student.find_by_url(params[:id])
      respond_to do |format|
        if @student.update_attributes(params[:student])
          format.html { redirect_to @student, notice: 'Student was successfully updated.'}  
        else 
          format.html { render action: "edit" } 
          format.json { render json: @student.errors, status: :unprocessable_entity } 
        end 
        end 
    end 

    #DELETE
    def destroy 
    @student = Student.find_by_url(params[:id])
    @student.destroy

        respond_to do |format|
         format.html { redirect_to students_url }
         format.json { head :no_content }
        end
    end
end 

編集#2:そうですか?

#GET /students/{:id}
    def show 
       @student = Student.find_by_url(params[:id])

        #BULLETS Randomizing /students/show.html.erb
    if cookies[:bullets].nil?
      @bullets = Bullet.all.shuffle.first(4)
      cookies[:bullets] = @bullets.collect(&:id)
    else
     @bullets = []
     cookies[:bullets].each do |id|
       @bullets << Bullet.find(id)
     end
    end

           respond_to do |format|
         format.html # show.html.erb
         format.json { render json: @student } 
           end  
    end
4

3 に答える 3

2

次のようになります。

#GET /students/{:id}
def show 

   @student = Student.find_by_url(params[:id])

   #BULLETS Randomizing /students/new.html.erb
   if cookies[:bullets].nil?
     @bullets = Bullet.all.shuffle.first(4)
     cookies[:bullets] = @bullets.collect(&:id)
   else
     # simpler to use an 'in list' for only 4 id's
     Bullet.where("id in (?)", cookies[:bullets])
   end

   respond_to do |format|
     format.html # show.html.erb
     format.json { render json: @student } 
   end  
end

配列のループをcookies「リスト内」の単一のステートメントに変換したことに注意してください。これにより、ルックアップ用に生成されたSQLが簡素化されます。

ただし、このコードをモデルにプッシュする必要があることは議論の余地があります。

class Bullet < ActiveRecord::Base

  NUM_USER_BULLETS = 4
  # fetch a random set of 
  def self.user_bullets
    Bullet.all.shuffle.first(NUM_USER_BULLETS)
  end
end

または似たようなもの。次に、コントローラーはより単純です。

#GET /students/{:id}
def show 

   @student = Student.find_by_url(params[:id])

   #BULLETS Randomizing /students/new.html.erb
   if cookies[:bullets].nil?
     @bullets = Bullet.user_bullets
     cookies[:bullets] = @bullets.collect(&:id)
   else
     # simpler to use an 'in list' for only 4 id's
     Bullet.where("id in (?)", cookies[:bullets])
   end

   respond_to do |format|
     format.html # show.html.erb
     format.json { render json: @student } 
   end  
end

コードをモデルに移行すると、コントローラーがよりシンプルになります。

于 2012-07-06T03:20:00.233 に答える
1
class StudentsController < ApplicationController
   before_filter :get_bullets, :only => [:show]


  def show

  end

  ... 


  protected

  def get_bullets
  #BULLETS Randomizing /students/new.html.erb
    if cookies[:bullets].nil?
      @bullets = Bullet.all.shuffle.first(4)
      cookies[:bullets] = @bullets.collect(&:id)
    else
     @bullets = []
     cookies[:bullets].each do |id|
       @bullets << Bullet.find(id)
     end
    end

  end



end
于 2012-07-06T03:19:43.767 に答える
1

「ランダムな弾丸」コードをアクションbefore_filter用にリファクタリングshowし、データベースでランダム化を実行することをお勧めします。これは、テーブル全体をロードして Ruby でランダム化を実行するよりも高速です。

class UsersController < ApplicationController
  before_filter :assign_bullets, :only => :show

  # ...

private

  def assign_bullets
    if cookies[:bullets]
      @bullets = cookies[:bullets].map { |id| Bullet.find(id) }
    else
      @bullets = Bullet.order('RANDOM()').limit(4)
      cookies[:bullets] = @bullets.map(&:id)
    end
  end
end
于 2012-07-06T03:22:44.607 に答える