3

私はこれらの Railscast エピソードに似たようなことをしています:

http://railscasts.com/episodes/165-edit-multiple

http://railscasts.com/episodes/52-update-through-checkboxes

問題は、それらが選択したモデルのみを変更しようとしていることです。すべてのモデルを更新する必要があります。

私が最初に気付いたのは、id not in ()期待どおりにすべてを返すわけではないため、空のリストの特別なケースを作成する必要があったことです。

このコードは機能しますが、あまり DRY ではないようです。少なくとも、通常のケースを 1 行にマージできるはずです。

def update_published
  if params[:book_ids].empty?
    Book.update_all(published: false)
  else
    Book.where(id: params[:book_ids]).update_all(published: true)
    Book.where("id not in (?)", params[:book_ids]).update_all(published: false)
  end
  redirect_to books_path
end

改善のためのアイデアをいただければ幸いです。

4

3 に答える 3

2

次のことをしないのはなぜですか:

def update_published
  Book.update_all(published: false)
  Book.where(id: params[:book_ids]).update_all(published: true)
  redirect_to books_path
end

それはより速く、かなり単純明快です。

于 2013-01-15T06:35:14.580 に答える
0

あなたはこのようにそれを行うことができます:

def update_published
    Book.transaction do
      Book.update_all(published: false)
      Book.scoped.find(params[:book_ids]).update_all(published: true) #Should be Lazyloaded. Testing Now
    end
end

トランザクションなので、かなり高速になります。また、「どこ」ではなく「検索」を使用する方法にも注意してください。私の意見ではそれはより良いです。少しすっきりしたコードになります。

注:しかし、なぜ毎回すべての本のエンティティを更新する必要があるのか​​疑問に思います。出版された本を1冊ずつ適切に追跡するのは賢明ではないでしょうか。1冊の本を更新するたびにすべての本IDを渡す必要がある場合は、問題が発生する可能性があります。このソリューションはあまりスケーラブルではありません。

あなたが持っているべきものはこれです:

def publish_book(book)
  book.published = true;
  book.save!
end

またはさらに良い:

#Book.rb
def publish
  self.published = true
  self.save #not 100% sure you need this. Anyone?
end

あなたができるときはいつでも(多くの人が同意する)「スキニーコントローラー、ファットモデル」アプローチに従うべきです。つまり、基本的にはモデルクラス内にできるだけ多くのコードを配置し、それを惜しまない場合はいつでも他の場所には配置しないということです。

于 2013-01-26T16:26:30.270 に答える
0

私はついにそれを理解しました。

def update_published
  Book.update_all(["published = id in (?)", params[:book_ids]])
  redirect_to books_path
end

私は昨日同様のことをしようとしていましたが?、それが記入されておらずwhere、私のIDでを実行しているというエラーが発生し続けました。今日、私はついに両方のパラメーターを配列にラップする必要があることに気づきました。

これに関する奇妙な注意点の1つは、私の仕様の一部を台無しにしてしまったことです。私はfalseをチェックしていましたが、それはnilを与えていました。ただし、データベースではfalseに設定されているようです。スペックをからに変更して、be(false)かなりbe_false安全になりました。

于 2013-01-15T15:52:50.977 に答える