bernat / best_in_place

A RESTful unobtrusive jQuery Inplace-Editor and a helper as a Rails Gem
http://blog.bernatfarrero.com/in-place-editing-with-javascript-jquery-and-rails-3/
1.2k stars 572 forks source link

respond_with_bip giving 500 internal server error. #474

Open codemilan opened 9 years ago

codemilan commented 9 years ago

I have been using best_in_place with ajax_datatables_rails gem. In datatable class, I have used join method to fetch the list of records as below:

class SongDatatable < AjaxDatatablesRails::Base
  include AjaxDatatablesRails::Extensions::Kaminari

  def_delegator :@view, :best_in_place
  def_delegator :@view, :link_to
  def_delegator :@view, :song_path
  def_delegator :@view, :autocomplete_album_name_albums_path
  def_delegator :@view, :autocomplete_artist_name_artists_path

  def sortable_columns
    # list columns inside the Array in string dot notation.
    # Example: 'users.email'
    @sortable_columns ||= [
                            'Song.name',
                            'Artist.name',
                            'Album.name'
                          ]
  end

  def searchable_columns
    @searchable_columns ||= [
                              'Song.name',
                              'Artist.name',
                              'Album.name'
                            ]
  end

  private

  def data
    records.map do |record|
      [
        nil,
        best_in_place(record, :name, :display_with => lambda { |v| v.blank? ? "( No name )" : v }, url: song_path(record)),
        best_in_place(record, :artist_name, :display_with => lambda { |v| v.blank? ? "( No artist )" : v }, url: song_path(record, obj: 'artist'), html_attrs: { "data-autocomplete" => autocomplete_artist_name_artists_path }),
        best_in_place(record, :album_name, :display_with => lambda { |v| v.blank? ? "( No album )" : v }, url: song_path(record, obj: 'album'), html_attrs: { "data-autocomplete" => autocomplete_album_name_albums_path })
      ]
    end
  end

  def get_raw_records
    Song.joins(:artist, :album).select("songs.id, songs.artist_id, songs.album_id, songs.name, artists.name as artist_name, albums.name as album_name")
  end
end

and the update action in controller class for processing in-place editing is as:

def update
    if params.key?(:obj) && params[:obj] == 'artist'
      @song = Song.find(params[:id])
      @artist = Artist.find_by_name(params[:song][:artist_name])
      unless @artist.blank?
        ActiveRecord::Base.transaction do
           @song.update_attributes({:artist_id => @artist.id})
           unless update_music_metadata?(@song, "artist")
            raise ActiveRecord::Rollback, "Can't Updated music file with artist #{@artist.name}-file write error."
           end
        end
      else
        ActiveRecord::Base.transaction do
          @artist = Artist.create!(name: params[:song][:artist_name])
          @song.update_attributes({:artist_id => @artist.id})
          unless update_music_metadata?(@song, "artist")
            raise ActiveRecord::Rollback, "Can't Updated music file with artist #{@artist.name}-file write error."
          end
        end
      end
      respond_with_bip @song
    elsif params.key?(:obj) && params[:obj] == 'album'
      @song = Song.find(params[:id])
      @album = Album.find_by_name(params[:song][:album_name])

      unless @album.blank?
        ActiveRecord::Base.transaction do
           @song.update_attributes({:album_id => @album.id})
           unless update_music_metadata?(@song, "album")
            raise ActiveRecord::Rollback, "Can't Updated music file with album #{@album.name}-file write error."
           end
        end
      else
        ActiveRecord::Base.transaction do
          @album = Album.create!(name: params[:song][:album_name])
          @song.update_attributes({:album_id => @album.id})
          unless update_music_metadata?(@song, "album")
            raise ActiveRecord::Rollback, "Can't Updated music file with album #{@album.name}-file write error."
          end
        end
      end
      respond_with_bip @song
    else
      @song = Song.find(params[:id])
      ActiveRecord::Base.transaction do
        @song.update_attributes!({:name => params[:song][:name]})
        unless update_music_metadata?(@song, "title")
          raise ActiveRecord::Rollback, "Can't Updated music file with title #{@song.title}-file write error."
        end
      end
      respond_with_bip @song
    end
  end

Now, when i edit record the new record gets updated in db but the table displays older one even after updation, only for artists and album. Now the question is, How to build proper response body for join queries, "respond_with_bip" method is giving error as "undefined method artist_name" when updating artist data(updated in db but not in view) and for album data( "undefined method album_name"). album _name and aritst_name col comes from join query. Also whats the use of option parameter in "respond_with_bip" method ?