apotonick / kaminari-cells

Kaminari pagination in Cells.
MIT License
23 stars 15 forks source link

Intended usage of `#paginate` is unclear, as are conventions for working with collections #1

Closed reconstructions closed 8 years ago

reconstructions commented 10 years ago

I think there is an issue with the documentation of the intended use of #paginate when using kaminari-cells and Cells 3.11.1 with a ViewModel.

With the typical Kaminari stuff in my musicians_controller.rb:

@musicians = Musician.page params[:page]

And the following app/cells/musician_cell.rb:

class MusicianCell < Cell::ViewModel
  include Kaminari::Cells

  def show
    render
  end

  # This works and renders a musician_link for a singular Musician
  def musician_link
    link_to(full_name(model), musician_url(model))
  end

  def full_name(musician)
    first_name = musician.user.first_name
    last_name = musician.user.last_name
    full_name = "#{first_name} #{last_name}"
  end
end

This in my app/views/musicians/index.html.haml:

%h1 Musicians:
%div
  %div
  - @musicians.each do |musician|
    = cell(:musician, musician).call
    %br
  = paginate @musicians

And this in my app/cells/musician/show.html.haml:

= musician_link

Everything works as intended, and a collection of Musicians is decorated, with the first_name and last_name of an associated User class concatenated.

The issue is that this doesn't actually seem to be using the kaminari-cells gem at all! I can remove include Kaminari::Cells from my Cell and the gem from my bundle, and all this still works.

On the other hand, I haven't been able to figure out to use #paginate in a Cell, as the documentation for kaminari-cells suggests. The documentation on working with collections in Cells is thin enough that I seem to be going about it wrong. If I use this approach:

class MusiciansCell < Cell::ViewModel
  include Kaminari::Cells

  def show
    render
  end

  def musicians_links
=begin
musicians_links is intended to render link_to's for each Musician, but instead renders the
Musician objects themselves, eg:
<Musician id: 1, user_id: 1, created_at: "2014-06-05 03:37:07", updated_at: "2014-06-05 03:37:07">

What is best practice for looping through a collection while decorating it in a ViewModel?
=end
    model.each do |mus|
      # doesn't render link_to with full_name
      link_to(full_name(mus), musician_url(mus))
    end

    # paginate model in a Cells method fails:
    # paginate model # Missing partial kaminari/paginator with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder, :haml]}. Searched in: * "/Users/reconstructions/Desktop/Coding 2013/Rails Apps/sfrc/app/cells"
  end

  # paginate model in a Cell fails:
  # paginate model # undefined local variable or method `model' for MusiciansCell:Class

  def full_name(musician)
    first_name = musician.user.first_name
    last_name = musician.user.last_name
    full_name = "#{first_name} #{last_name}"
  end
end

This renders the Musician objects themselves (instead of a decorated collection of associate object attributes), and if I try to use paginate in a Cell per the documentation, I get errors.

If I could figure out how it would be best to do this kind of thing with kaminari-cells, I would like to put some different use-cases together in the Wiki for the benefit of other users.

I have been able to find almost nothing on working with collections in Cells. If the intended usage is looping in views using controller instance variables with calls to the Cells, then I suppose this is OK. If I am missing something, and there are conventions on looping in Cells, then I would like to try to add something to the documentation on that. Since pagination always involves working with collections, this would be helpful for this gem as well.

Thanks in advance for any help on this.

apotonick commented 10 years ago

Thanks for your report! Documenting/extending this (unreleased) gem sounds fantastic, please help me out with it!!!

  1. Are you using the kaminari master branch? The feature that allows cells to use kaminari is not released, yet, on the kaminari side.
  2. The only method that currently is supported in kaminari-cells is #paginate, which is included into the view model with include Kaminari::Cells.

Please go grab the master branch from kaminari and try using #paginate in your cell, then we can discuss the collection problem. Are you talking about rendering collections of cells in general or what exactly do you miss???

reconstructions commented 10 years ago

I like writing documentation that helps with the basic problems the most new developers seem to have with certain gems when they are just starting out, or when the api for the gems has changed/is changing a lot. FactoryGirl is one that seems to confuse a lot of people when using associations, for example, so I have been working on a basic tut for that.

The Kaminari I am using in the above examples is gem 'kaminari', '~> 0.15.1'. I took a look at lib/kaminari/helpers/tags.rb. I have this in my Gemfile for 'kaminari-cells': gem 'kaminari-cells', :git => 'https://github.com/apotonick/kaminari-cells.git'.

In the above implementation I tried using paginate in my cells a couple different ways, but I think I have the syntax wrong:

class MusiciansCell < Cell::ViewModel
  include Kaminari::Cells

  def show
    render
  end

  def musicians_links
    model.each do |mus|
      # doesn't render link_to with full_name
      link_to(full_name(mus), musician_url(mus))
    end

    # paginate model in a Cells method fails:
    paginate model #=> Missing partial kaminari/paginator with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder, :haml]}. Searched in: * "/Users/reconstructions/Desktop/Coding 2013/Rails Apps/sfrc/app/cells"
  end

  # paginate model in a Cell fails:
  paginate model #=> undefined local variable or method `model' for MusiciansCell:Class

  def full_name(musician)
    first_name = musician.user.first_name
    last_name = musician.user.last_name
    full_name = "#{first_name} #{last_name}"
  end
end

Also spent some time in Byron Bay when I was diving in Oz. My best dives ever were in the Northern Solitary Islands. Saw Black Flag a bunch in the 80's as well. No lingering injuries from that...

With collections my question is about the intended use case for Cells. If they are intended to be used with singular resources, then where does pagination fit in? If they work with collections, then it would be good to put together some examples. This is the only example of working with a cell collection I have found, and I haven't been able to get anything like this working with ViewModels. So I guess it is really a question of intended use case.

apotonick commented 10 years ago

Hey, cool that you've been to Byron, it's a nice place, isn't it? Very small, though. I definitely wanna try diving, been "busy" with surfing so far :wink: Gonna see Propagandhi tomorrow :dancers:

As already stated, you're using the wrong kaminari gem, you have to use github version.

gem 'kaminari', git: "https://github.com/amatsuda/kaminari.git"

It will then work as expected.

I'm not sure if I understand the collection problem in combination with pagination. The newest version of cells comes with support for rendering collections of cells.

Cell::ViewModel.cell(:song, collection: Song.all)

Does that help?