Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails link_to update attribute from controller action

I want to be able to have a link that when pressed updates one attribute based up a controller action. How would I be able to do this? Do I have to create a separate update route? I am new at this so please bear with me.

controller

def completed
 @meeting = Meeting.find(params[:id])
 if @meeting.day_of_meeting == @meeting.days
  @meeting.update_attribute(:day_of_meeting, '1')
  redirect_to :back
 else
  @meeting.increment!
  redirect_to :back
 end
end

model

def increment!
  update_attribute(:day_of_meeting, day_of_meeting + 1)
end

view

<%= link_to meetings_completed_path(@meeting), remote: true do %>

routes

resources :meetings do
  get 'meetings/completed'
end
like image 362
user2004710 Avatar asked Feb 13 '23 17:02

user2004710


1 Answers

There are several issues with your code

  1. Since you are updating a record you need to include method: :patch in your link and also you need to modify the routes file to include appropriate route.

    In your routes file add

    #routes.rb
    resources :meetings do
      member do
        patch 'completed'
      end
    end
    

    In your view

    <%= link_to "Mark as completed", completed_meeting_path(@meeting), remote: true, method: :patch  %>
    
  2. Since you have a remote:true in your link so rails will try to render a javascript template and since you are not rendering a javascript template you will get a template missing error

    In your controller

    def completed
      @meeting = Meeting.find(params[:id])
      respond_to do |format|
        # if something ...
          # update meeting record and then render js template
          format.js {render :status => :ok} # it will render completed.js.erb inside 'app/views/meetings/' directory
        # else
          # something else
          format.js {render :action => "different_action"} # it will render different_action.js.erb inside 'app/views/meetings/' directory 
      end
    end 
    

Now all you need to do is to write some basic javascript in the js templates to update the view.

Note : If you don't want to render anything simply use format.js { render :nothing => true }. Also if you want to use redirect_to calls instead of rendering js template just remove remote: true form you link .

like image 126
Monideep Avatar answered Feb 15 '23 08:02

Monideep