How to pass variable into controller action from view? - ruby-on-rails

views/vehicles/_form.html.haml
= link_to "Deactivate", "/vehicles/deactivate"
I want to pass in #vehicle in my link_to above.
How do I do this?
controllers/vehicles_controller.rb
def deactivate
#vehicle = Vehicle.find(params[:id])
#vehicle.active = 0
#vehicle.save
respond_to do |format|
format.html { redirect_to vehicles_url }
format.json { head :no_content }
end
end

To make it easy and in Rails way, you can use Rails resources:
# routes.rb
resources :vehicles do
put 'deactivate', on: :member
end
# view:
= link_to 'Deactivate', deactivate_vehicle_path(#vehicle), method: :put

Best answer already given by Marek Lipka.
There is also a way using ajax
<%= link_to 'Deactivate', javascript::void(0), :class => "deactivate" %>
Put some script:
<script>
$(".deactivate").click(function() {
$.ajax({
type: "post",
url: "/vehicles/deactivate",
data: {id: <%= #vehicle.id %>},
dataType:'script',
beforeSend: function(){
// do whatever you want
},
success: function(response){
// do whatever you want
}
});
});
</script>

This worked for me, I ended up using the Update action in my controller.
= link_to "Deactivate", vehicle_path(#vehicle, :vehicle => {:active => 0}), method: :put, :class=>'btn btn-mini'

Related

Rails how to update the page with the help of Ajax

The object Task contains a boolean field done. How to Ajax refresh the page after the change of status? And instead true - false display value complete - incomplete?
routes.rb:
resources :tasks do
member do
post 'done'
end
end
Controller:
def done
#task = Task.find(params[:id])
#task.update_attributes(:done => params[:done])
respond_to do |format|
format.js {}
end
end
View:
....
<td><%= task.done %></td>
<td><%= check_box_tag 'done', task.id , task.done, :class => "task-check", remote: true %></td>
....
<script>
$(".task-check").bind('change', function(){
$.ajax({
url: '/tasks/'+this.value+'/done',
type: 'POST',
data: {"done": this.checked},
});
});
</script>
Update
edited script
<script>
$(".task-check").bind('change', function(){
$.ajax({
url: '/tasks/'+this.value+'/done',
type: 'POST',
data: {"done": this.checked},
}).done(function(ajax_response){
location.reload();
});
});
</script>
and controller
def done
#task = Task.find(params[:id]) # make sure you have this
#task.update_attributes(:done => params["done"])
render :json => { data: "Success", is_done: params[:done] }
end
How to update page content without having to reboot ?
Controller:
def done
#task = Task.find(params[:id]) # make sure you have this
#task.update_attributes(:done => params["done"])
render :json => { data: "Success", is_done: params[:done] }
end
View:
....
<td><%= task.done %></td>
<td><%= check_box_tag 'done', task.id , task.done, :class => "task-check" %></td>
....
<script>
$(".task-check").on('change', function(e){
// removed remote-true. you can preventDefault if you need to but doubt page tries to refresh from a checkbox getting checked. e.preventDefault() if you need it
$.ajax({
type: "POST",
url: '/tasks/done',
type: 'POST',
data: {done: $('.task-check').val()},
}).done(function(ajax_response){
// update whatever you want after it completes
});
});
</script>
Didn't test this but I write these all the time. Let me know if it doesn't work post the payload and I'll figure out what's missing.
If you just want to update the value from 'incomplete' to 'complete', you can simply target the element that's called incomplete. if it has a class of, say, 'task-status' you can target that element and update in the .done part of the function. For instance:
$('.task-status').text('Complete')
should replace what previously said incomplete. If it's a text input you might use .val() instead. If it's just text on the page .text() should work.

Checkbox in index view live updating

I'm currently learning rails and working on what I'm sure is everyone's first rails app, a simple todo list. I need to implement a checkbox next to the items to indicate whether they are complete or not. Each item has a boolean attribute called "completed" in their model. I have found a couple checkbox questions while searching but none explain the syntax very easily in the context of the index view.
Also, I really want the checkbox to work without a submit button. I know I could accomplish something like this using AngularJS's ng-model but I don't think it would be practical to implement angular for such a small thing and I don't know how angular works with rails.
If anyone could give me a pointer in the right direction, it would be greatly appreciated. Here's my index.html.erb for reference.
<h1>
To Do List
</h1>
<table>
<tr>
<% #todo_items.each do |item| %>
<!-- Checkbox here -->
<tc style="<%= 'text-decoration: line-through' if item.completed %>">
<%= link_to item.title, item %>
</tc>
<tc>
<%= item.description %>
</tc>
<tc>
<%= link_to "Edit", edit_todo_item_path(item) %>
</tc>
<tc>
<%= link_to "Delete",item, data:{:confirm => "Are you sure you want to delete this item?"}, :method => :delete %>
</tc>
<hr/>
<% end %>
</tr>
</table>
<p>
<%= link_to "Add Item", new_todo_item_path %>
</p>
This is my way, I don't know this way is right direction or not but this works for me (also different case but same of concept).
views for checkbox
You could put an id item or something into attribute of checkbox for find an object in controller if you send data to controller for get record of object, and you could define if attribute completed of record is true or false:
<%= check_box_tag :completed_item, 1, item.completed? ? true : false, { class: 'name-of-class', data: { id: item.id} } %>
controller
You need two action call set_completed and remove_completed, and also you don't need templates for them, just use format as json:
before_action :set_item, only [:set_completed, :remove_completed, :other_action]
def set_completed
#item.set_completed!
respond_to do |format|
format.json { render :json => { :success => true } }
end
end
def remove_completed
#item.remove_completed!
respond_to do |format|
format.json { render :json => { :success => true } }
end
end
private
def set_item
#item = Item.find params[:id]
end
Model
For set_completed! and remove_completed! you could define in your model
def set_default!
self.update_attributes(:completed => true)
end
def remove_default!
self.update_attributes(:completed => false)
end
routes
resources :address do
collection do
post 'set_completed'
post 'remove_completed'
end
end
Also, you need help JavaScript for handle send request from view to controller event click of checkbox:
jQuery
$(".completed_item").click(function(){
var check = $(this).is(":checked");
if (check == true){
set_completed($(this).attr('data-id'));
} else{
remove_completed($(this).attr('data-id'));
}
});
function set_completed(data_id) {
$.ajax({
type: 'POST',
url: "/items/set_completed",
data: { id: data_id},
dataType: 'json',
success: function(response){
if(response){
}else{
alert('error');
}
}
})
}
function remove_compelted(data_id) {
$.ajax({
type: 'POST',
url: "/items/set_completed",
data: { id: data_id},
dataType: 'json',
success: function(response){
if(response){
}else{
alert('error');
}
}
})
}

Rails - rendering a search result in json to a form

My class Contribution belongs_to User. I have a form for a new contribution which includes a search field for for the user to whom the contribution will belong -
in /contributions/new.html.erb -
<%= text_field_tag :search, params[:search], id: "search" %>
<%= link_to "Search", search_contributions_path, id: "search_submit" %>
in application.js.erb
$(document).on("click", "a#search_submit", function(){
$.ajax({
url: $(this).attr("href"),
data: {query: $("#search").val() },
success: function(data) {
var user = $.parseJSON(json);
}
});
});
and in contribution_controller.rb -
def search
#users = User.search(params[:search])
render :users => #users.to_json
end
My controller is trying to render a page - how do I make it return the result I want to the view?
you could write:
render json: { users: #users.to_json }
Wouldn't a respond_to fix that? Something like
respond_to :html, :xml, :json
depending on the formats you want to "respond to", obviously.
Here's the source http://apidock.com/rails/ActionController/MimeResponds/ClassMethods/respond_to
You must use the following in your controller:
respond_to :html, :xml, :json
And You can return json as the following:
respond_to do |format|
format.json { render json: #users.result() }
end
Or as the following:
render json: { :users => #users.result().to_json }
I think you used ransak for searching, so you need use #users.result().to_json instead of #users.to_json
The issue is not related to json, your issue is related to javascript change your ajax call to be:
$(document).on("click", "a#search_submit", function(e){
e.preventDefault();
$.ajax({
url: $(this).attr("href"),
data: {query: $("#search").val() },
success: function(data) {
var user = $.parseJSON(json);
}
});
});

Rails call a method from within a different view

I am trying to call a method of one controller from within a different view.
I saw the following post Rails call destroy method from within another controller, but I am doing something wrong with my implementation.
The method I am trying to call is in an accessor controller.
def remove_permission_from_index
Accessor.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to tasks_url }
format.json { head :no_content }
end
end
This controller also has the following strong param method
def accessor_params
params.require(:accessor).permit(:accessor_id, :access_rights, :task_id)
end
My view is calling the following code
<%= link_to 'Delete', {:controller => "accessors", :accessor => elem} ,method: :remove_permission_from_index, data: { confirm: "Are you sure?" }%> </p>
where elem an element within a set that is defined in the task controller
#canEdit = Accessor.select(:task_id).where("accessor_id = ? AND access_rights = ?", current_user, true)
#canEdit.each do |p|
p.task = Task.find(p.task_id)
When I am running my code I am getting the following error
param not found: accessor
def accessor_params
params.require(:accessor).permit(:accessor_id, :access_rights, :task_id)
end
end
and I can see that the accessor param is not being passed :
Parameters:
{"_method"=>"remove_permission_from_index"}
a) why is the accessor_params is being called if I am trying to access a different method
b) what am I doing wrong? After all I do set :accessor => elem
Could be a copy paste error but:
<%= link_to 'Delete', {:controller => "accessors", :accessor => elem} ,method: :remove_permission_from_index, data: { confirm: "Are you sure?" }%> </p>
should be more like:
<%= link_to 'Delete', {:controller => "accessors", :action => :remove_permission_from_index, :accessor => elem}, method: :delete, data: { confirm: "Are you sure?" }%> </p>

refreshing a partial's variables with ajax

Rails 3.2
jQuery-Rails
I've searched all over and I've only found js ways to update a partial or add a partial via JS. I've had no luck with this one. Here is the issue:
I have a list of referrals on a page, the referrals are posted on the index page as partials. The referral box has a reply button and a count of how many replies per referral. Statically I had it working but I'm getting no luck with updating the referral box with the new count and replacing the reply button with an icon. The is getting to the database but I'm screwing something up with the refresh of the box. Help please!
Do I use locals to render the new variables?
Should I remove my if statements from the partial and just use the js.erb file to determine what to show?
Reply controller:
class RepliesController < ApplicationController
respond_to :html, :js
def new
#referral = Referral.find(params[:referral_id])
#reply = #referral.replies.new(:user_id => params[:user_id], :referral_id => params[:referral_id])
if #reply.save
format.html { notice: 'Replied' }
respond_with(#referral, :location => referrals_path)
end
end
end
_referral partial:
.referralBox.cornerShadow{:id => "Referral#{referral.id}"}
- if current_user == referral.user or current_user.role == 'administrator'
= link_to '<i class="icon-pencil icon-large icon-grey" rel="tooltip" title="Edit"></i>'.html_safe, edit_referral_path(referral), class: "referralEdit"
= link_to '<i class="icon-remove icon-large icon-grey" rel="tooltip" title="Delete"></i>'.html_safe, referral, method: :delete, data: { confirm: 'Are you sure?' }, class: "referralClose"
.referralProfile
= link_to "#{image_tag(referral.user.image.url, :class => "img-circle img-border border-white", :style => "thumb")}".html_safe, referral.user
%ul.unstyled.inline
%li
= referral.description
- unless referral.replies.count == 0
- if referral.user == current_user
%i.icon-comments.icon-large{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- else
%i.icon-comments.icon-large.orange{"rel" => "tooltip", "title" => "Replies"}
= referral.replies.count
- unless current_user == referral.user
- if referral.replies.any?
%i.icon-ok.icon-large.pull-right.orange{"rel" => "tooltip", "title" => "Replied"}
- else
= link_to '<i class="icon-ok icon-large pull-right icon-grey" rel="tooltip" title="Reply"> Reply</i>'.html_safe, new_referral_reply_path(:referral_id => referral.id, :user_id => current_user.id), :id => "ReplySubmit", :remote => true
new.js.erb view
$(".referralBox").html("<%= j(render(:partial => "#referral")) %>");
application.js
jQuery.ajaxSetup({
'beforeSend': function (xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

Resources