ActionController::InvalidAuthenticityToken on delete form Rails 4 - ruby-on-rails

I have a problem with Rails 4 and deleting multiple items in a database.
I am working on creating an email inbox and I would like to move an item into the "trash folder" and after that I want to redirect the user to the trash page, where he can delete the item from the database.
My code:
routes.rb
namespace :admin do
resources :inboxes do
collection do
match 'destroy_multiple' => 'inboxes#destroy_multiple', via: ['post','delete']
get 'sent'
get 'trash'
end
end
end
controller :
def destroy_multiple
if params[:action] == 'trash'
#del = Inbox.where(:id => params[:delete]).destroy_all
else
#del = Inbox.where(:id => params[:delete]).update_all(:folder =>'trash')
end
redirect_to admin_inboxes_path
end
And finally, my form (slim) :
= form_tag destroy_multiple_admin_inboxes_path, method: :delete, class: "multiple_delete" do
input type="hidden" name="action" value = controller.action_name
- #inboxes.each do |msg|
- #username = msg.email.gsub(/([^.]+)#.+/, '\1').gsub(/[^0-9A-Za-z]/, ' ').split.map(&:capitalize).join(' ')
tr class=(msg.read == 1 ? nil : 'unread')
td.inbox-small-cells
label.checkbox-custom.check-success
= check_box_tag "delete[]", msg.id, false, class: "for_del", id: "delete_#{msg.id}"
label for="delete_#{msg.id}"
td.inbox-small-cells
i.fa.fa-star.inbox-started
td
a.avatar href="/fr/admin/inboxes/#{msg.id}"
span.bg-primary =#username[0]
td.view-message.dont-show = #username
td.view-message = msg.subject
td.view-message.inbox-small-cells
td.view-message.text-right = msg.created_at.strftime("%d/%m")
I can with this code successfully move mail to the "trash", but I cannot delete them from the database.
Thank you!

You need to add the authenticity_token to your form. Try:
form_tag destroy_multiple_admin_inboxes_path, method: :delete, class: "multiple_delete", authenticity_token: true do
If you're working with a specific active record object, use form_for instead of form_tag, and the csrf field will automatically be built into the form by rails. However, this is a good time to be using form_tag.
The alternative solution is to change the config config.action_view.embed_authenticity_token_in_remote_forms to false, but this will make your site less secure, and it's better to just add authenticity_token: true to your form_tag.
Here is the documentation on form_tag

Related

Ruby on Rails link_to method to change db value

Hello I am trying to change a string value from "no" to "yes" in my Rails Postgresql db based on if a user clicks a yes or no button using the link_to method in my view. I have designated the default string value to "no" so I would like the value to change to yes if a user clicks the yes button . I would like assign the 'link_to method' to the yesmarried action in my controller.I =m not sure how to locate the the newcase in the yesmarried action and I keep getting the error Couldn't find Newcase without an ID
here is my controller
class NewcaseController < ApplicationController
def new
end
def create
#newcase = NewCase.new(newcase_params)
end
def yesmarried
#newcase=Newcase.find(params[:id])
self.married = "yes"
end
private
def newcase_params
params.require(:newcase).permit(:state,:first_name,:last_name, :dob, :email, :telephone_number, :addr,:respondent_fname, :respondent_lname,:respondent_addr, :marriage_date, :state_of_marriage, :date_of_seperation, :number_of_children, :children_addr, :occupation , :work_addr, :net_monthly, :married)
end
end
here is my view:
<%=link_to 'yes',new_path(#newcase), class:"btn btn-lg rounded btn-warning", action: "yesmarried",method: "put", "data-toggle" => "modal", 'data-target' => '#married-question', "data-bs-dismiss"=>"modal" %>
routes file:
get '/new', to:'newcase#new'
post '/new', to:'newcase#create'
patch '/new', to:'newcase#yesmarried'
put '/new', to:'newcase#yesmarried'
Your code is a little unrestful and non-idiomatic but your yesmarried method should read:
def yes_married
#newcase = Newcase.find(params[:id])
#newcase.update_attribute(:married, 'yes')
end
Add the route:
get '/newcase_yes_married`, to: 'newcase#yes_married'
You'd need to change new_path to newcase_yes_married_path (or whatever path rails routes returns in the terminal).
However a better solution would be to piggyback an update method to keep it RESTful.
def update
#newcase = Newcase.find(params[:id])
#newcase.update_attributes(newcase_params)
end
<%= link_to "Yes", [#newcase, { newcase: { married: 'yes' }}], method: 'patch' %>
Note: code not tested.

Change View based on Option selected in select_tag in rails

I am trying to make a form where a user can wither post normally with their username like this - > normal
=form_for #confession , html: {multipart: true} do |f|
=f.label :Confess
=f.text_area :confession , require: true
=f.file_field :confessionimage
=f.select (:id,options_for_select(ID))
=f.submit 'Confess'
or Anonymously where their Names will be hidden and no one will know that who posted this post .. for this what I thought was I will make a user named anonymous in database and if a user select anonymous in select_form while posting they will post as an anonymous user.
for this in my controller I want something like this and main point that I can't understand is how can the controller know what user has selected ?
this is my controller
def index
#amitian = Amitian.where(institute: current_amitian.institute) if amitian_signed_in?
#confessions = Confession.where(amitian_id: #amitian.ids).order('created_at DESC') if amitian_signed_in?
#confession = current_amitian.confessions.build
#anonymous = Amitian.where(email: anonymous#anonymous.com)
# (if anonymous selected )
do #anonymous.confessions.build
end
To access this :id params you use confession_params[:id], or params[:confession][:id]
If you want to conditionally load different views you could use a respond_to block like this:
if confession_params[:id] == 1 #or params[:confession][:id] == 1
loaded_view = :foo
else
loaded_view = :bar
end
respond_to do |format|
format.html { render loaded_view }
end
This would load foo.html.erb or bar.html.erb, based on you #confession :id parameter, passed by your select on form_for tag, which loads parameter names based on your view's variable model.

How to “dynamically add options” to 'form_for'?

I am using Ruby on Rails 3.2.2. In order to implement a "dynamic generated" AJAX style file upload form I would like to "dynamically add options" to the FormHelper#form_for statement if some conditions are meet. That is, at this time I am using code as-like the following (note that I am using the merge method in order to add options to the form_for method):
<%
if #article.is_true? && (#article.is_black? || && #article.is_new?)
form_options = {:multipart => true, :target => "from_target_name"}
else
form_options = {}
end
%>
<%= form_for(#article, :remote => true, :html => {:id => "form_css_id"}.merge(form_options)) do |form| %>
...
<% end %>
However, I think that the above code is too much hijacked.
Is there a better way to accomplish what I am making? For example, can I access from view templates some (unknown to me) instance variable named as-like #form and "work" on that so to change related options as well as I would like? Or, should I state a helper method somewhere? How do you advice to proceed?
BTW: Since the upload process is handled by using a HTML iframe, I am using the remotipart gem in order to implement the AJAX style file upload form - I don't know if this information could help someone...
This looks like a good candidate for a helper method. In your view:
<%= form_for(#article, :remote => true, :html => article_form_options(#article, :id => "form_css_id")) do |form| %>
...
<% end %>
In app/helpers/articles_helper.rb
module ArticlesHelper
def article_form_options(article, defaults = {})
extras = if article.is_true? && (article.is_black? || article.is_new?)
{ :multipart => true, :target => 'form_target_name' }
else
{}
end
defaults.merge(extras)
end
end
Helpers are a good place to keep logic that's too complex for a view but still related to the view.

Rails 3.1 pass data through a post

In my application, I've a 'warehouse' model that own several fields such as id,name,description, etc, and a boolean field called 'done'.
In my view, I want to insert a button or link field,which, when clicked, should set (through HTTP POST method) warehouse.done = true
How can I do this?
Notes: User cannot input warehouse.done field so I suppose to pass it to application as hidden field
Use link to with remote option.
<%= link_to "Vote", {:controller=>"your_controller_name", :action => 'vote',:id=>#warehouse.id, :vote=>true}, :remote=> true, :method => :put %>
In your controller
def vote
#warehouse = Warehouse.find(params[:id])
#warehouse.update_attribute(:vote, params[:vote])
respond_to do |format|
format.js
end
end
In your routes file
resources :your_controller_name do
collection do
put 'vote'
end
end
In your voting view page add new DIV to display flash notice.
<div id="flash_notice" style="display: none;"></div>
Create new RJS template "vote.js.erb" with following code.
$("#flash_notice").html("You have voted successfully");
$("#flash_notice").show("slow");
Let me know if you have any problem.
I made a couple of assumptions on the views, controller.
html
DONE
<input id="warehouse-id" type="hidden" value="24">
js
$(document).ready(function() {
$('#set-warehouse-done').click(function() {
$.ajax({
url: '/warehouse/' + $('#warehouse-id').attr('value');
type: 'POST'
data: done: true
});
});
}
warehouse_controller.rb
def update
#warehouse = Warehouse.find(params[:id])
if params[:done]
if #warehouse.update_attributes(:done, params[:done])
flash[:notice] = 'Warehouse updated successfully'
else
flash[:error] = 'Could not update warehouse'

Making cookies for search options?

I need help on creating these cookies for my Search options. I've read the Rails Guide and API but still don't understand how to make cookies correctly. I have two checkboxes that filter search results. They start out as already checked but what I need it to do is save the settings in a cookie if one of them is unchecked for the next searches. Here is a picture for better understanding:
Answer:
class SearchController < ApplicationController
def index
#title = "Search"
#page_title = "Search"
# Checkboxes are already checked.
params[:online_search_checked] = true
params[:offline_search_checked] = true
restore_cookie # if user enters this page in the future we restore checkboxes state from the cookies. For the first visit checkbox value will be true.
end
def results
update_cookie # each time user submits search we need to update cookies.
restore_cookie # each time user submits search we need to show search page with correctly checked check boxes.
#title = "Search"
#page_title = "Search"
#search = Product.search do |q|
q.fulltext params[:search]
q.with(:coordinates, params[:coordinates]).near(latitude, longitude, :precision => 3) if params[:coordinates].present?
q.with(:online_search, false) if params[:online_search].nil? # search user prices that are online automatically if checkbox is checked.
q.with(:offline_search, true) if params[:offline_search].nil? # search user prices that are offline automatically if checkbox is checked.
q.paginate(:per_page => 20, :page => params[:page])
q.order_by(:purchase_date, :desc)
q.order_by(:price,:asc)
end
#products = #search.results
end
def update_cookie
update_cookie_with_param(:online_search, :online_search_checked)
update_cookie_with_param(:offline_search, :offline_search_checked)
end
def restore_cookie
restore_param_from_cookie(:online_search_checked)
restore_param_from_cookie(:offline_search_checked)
end
def update_cookie_with_param(value_param_name, checked_param_name)
checked = params[value_param_name].nil? ? "false" : "true"
cookies[checked_param_name] = { :value => checked, :expires => 2.weeks.from_now }
end
def restore_param_from_cookie(checked_param_name)
if cookies[checked_param_name]
params[checked_param_name] = (cookies[checked_param_name] == "true")
end
end
end
# On index and result page in partial
<%= form_tag results_search_index_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<%= label_tag :online_search, 'Online' %>
<%= check_box_tag :online_search, 'online_search_value', params[:online_search_checked] %>
<%= label_tag :offline_search, 'Offline' %>
<%= check_box_tag :offline_search, 'offline_search_value', params[:offline_search_checked] %>
<% end %>
Cookie is a message given to a Web browser by a Web server. The
browser stores the message in a text file. The message is then sent
back to the server each time the browser requests a page from the
server.
In rails you can use cookies, cookies.permanent and cookies.signed to write cookies:
cookies - simple session cookies
cookies.permanent - create cookies
with expiration date 20 years in the future
cookies.signed - generate
signed representation of cookie to pvervent tampering of its value by
the end user.
To explain cookies usage I created two session cookies for your application: 'online_search_checked' and 'offline_search_checked'. They contain "true" or "false" values and represent whether appropriate checkbox is checked or not.
check_box_tag has following parameters: checkbox_name, checkbox_value, is_checked. We need to modify third parameter depending on the value received from the cookie. The second value may be a constant. If checkbox is checked, then params[:checkbox_name] == checkbox_value. If checkbox is unchecked, then params[:checkbox_name] == nil.
Here is the algorithm:
The first time when user hits 'search/index' he does not have
'online_search_checked' and 'offline_search_checked' cookies set.
Then you would like to show him both check boxes checked by default.
If this is not the first time then user already has cookies set and
we need to restore state of checkboxes from these cookies.
When user hits 'search/results' we update cookies with the current state of checkboxes
and restore state of checkboxes from these cookies.
Here is the code with my comments:
class SearchController < ApplicationController
def index
params[:online_search_checked] = true
params[:offline_search_checked] = true
restore_cookie # if user enters this page in the future we restore checkboxes state from the cookies. For the first visit checkbox value will be true.
end
def results
update_cookie # each time user submits search we need to update cookies
restore_cookie # each time user submits search we need to show search page with correctly checked check boxes
# Using Sunspot here.
#search = Product.search do |q|
q.fulltext params[:search]
q.with(:online_search, params[:online_search] == 1) if params[:online_search].nil?
q.with(:offline_search, params[:offline_search] == 0) if params[:offline_search].nil?
end
#products = #search.results # Sunspot rendering results.
end
def update_cookie
update_cookie_with_param(:online_search, :online_search_checked)
update_cookie_with_param(:offline_search, :offline_search_checked)
end
def restore_cookie
restore_param_from_cookie(:online_search_checked)
restore_param_from_cookie(:offline_search_checked)
end
def update_cookie_with_param(value_param_name, checked_param_name)
checked = params[value_param_name].nil? ? "false" : "true"
cookies[checked_param_name] = { :value => checked, :expires => 2.weeks.from_now }
end
def restore_param_from_cookie(checked_param_name)
if cookies[checked_param_name]
params[checked_param_name] = (cookies[checked_param_name] == "true")
end
end
end
# On index and result page in partial
<%= form_tag 'results', :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
<%= check_box_tag :online_search, 'online_search_value', params[:online_search_checked] %>
<%= check_box_tag :offline_search, 'offline_search_value', params[:offline_search_checked] %>
<% end %>
Hope this helps!
UPDATE
I do not quite understood what do you want to do here:
q.with(:online_search, params[:online_search] == 1) if params[:online_search].nil?
q.with(:offline_search, params[:offline_search] == 0) if params[:offline_search].nil?
In your code params[:online_search] == 1 and params[:offline_search] == 0 expressions will always be false because params[:online_search] and params[:offline_search] are nil according to if condition.

Resources