Ruby on Rails: Destroy action displays an error - ruby

If you execute the destroy action, you will get such an error.
URL:http://localhost:3000/listings/test
View
<% #alllistings.all.order(created_at: :desc).each do |listing| %>
<tbody>
<tr>
<th scope="row">
<%= link_to listing_path(listing) do %>
<span class="listing-title"><%= listing.listing_title %></span>
<% end %>
</th>
<td>
<%= link_to "delete",[listing],method: :delete, data: {confirm: "Are you sure?"} if current_user = listing.user %>
</td>
</tr>
</tbody>
<% end %>
Controller
class ListingsController < ApplicationController
before_action :set_listing, only: [:destroy]
def index
#alllistings = current_user.listings
end
def destroy
#listing.destroy
return reedirect_to listings_path, notice: "削除しました", :status => :moved_permanently
end
private
def set_listing
#listing = Listing.friendly.find(params[:id])
end
end
Model
class Listing < ApplicationRecord
validates :listing_title, presence: true
include FriendlyId
friendly_id :listing_title
def should_generate_new_friendly_id?
listing_title_changed?
end
end
rails 5
We are using gem 'friendly_id'.
We also introduced slug.
Please answer me my question.

Please try to use in your view.
<%= link_to "delete",listing_path(listing), method: :delete, data: {confirm: "Are you sure?"} if current_user = listing.user %>

Related

Grouping records by user in Admin view

I would like to get all records with their usernames when signed in as Admin. For that my controller code is as below;
amol361s_controller.rb
def index
if current_user.admin
#amol361s = Amol361.all.search(params[:search]).order("created_at ASC")
#users = User.all.amol361s
else
#amol361s = current_user.amol361s.all.search(params[:search]).visible.order("created_at ASC")
end
respond_to do |format|
format.html
format.js
end
end
index.html.erb
<tbody id = "kola">
<% #users.each do |user| %>
<%= user.amol361s.each do |amol361| %>
<tr class="tr-<%= cycle('odd', 'even') %>" id='<%= "tr_#{amol361.id}" %>'>
<% if current_user && current_user.admin %>
<td class="col-1"><%= link_to amol361.date.try(:strftime,'%d/%m/%Y'), edit_amol361_path(amol361) %></td>
<% else %>
<td class="col-1"><%= amol361.date.try(:strftime,'%d/%m/%Y') %></td>
<% end %>
<td class="col-3"><%= span_with_possibly_red_color amol361.description %></td>
<td class="col-1"><%= number_with_precision(amol361.amount, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 neg"><%= number_with_precision(amol361.discount, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 neg"><%= number_with_precision(amol361.paid, :delimiter => ",", :precision => 2) %></td>
<% #balance += amol361.amount.to_f - amol361.discount.to_f - amol361.paid.to_f %>
<% color = #balance >= 0 ? "pos" : "neg" %>
<td class="col-1 <%= color %>"><%= number_with_precision(#balance.abs, :delimiter => ",", :precision => 0) %></td>
<td class="col-1"><%= amol361.delndel %></td>
<td class="col-1"><%= amol361.remark %></td>
<% if current_user && current_user.admin %>
<td class="col-1"><%= link_to "Hide", hide_amol361_path(amol361), method: :put, remote: true, style: "color:#bb7272;" %>
<%= link_to amol361, method: :delete, data: { confirm: "Are you sure?" }, :class => 'delete_item' do %>
<i class="fa fa-trash" ></i>
<% end %>
</td>
<% end %>
</tr>
<% end %>
<% end %>
</tbody>
Right now I am getting the error as undefined method amol361s' for # User::ActiveRecord_Relation:0x00007f5dec19d088.
So, I am trying to get the records followed by usernames, similar to how we gather records based on month.
Any suggestions are most welcome.
Thank you in advance.
From what I understand, you can simply eager load user records if the current user is admin, like this:
#amol361s = Amol361.includes(:user).search(params[:search]).order("created_at ASC")
If you do this, it will be effective to fetch the user data simply by calling association on each member of this relation, like this:
# example:
#amol361s.first.user.username # or whatever the name of username column is
I'm not sure I understood your question correctly though, cause it's a little bit unclear to me.

approve multiple records at once

how to achieve this Scenario:
admin to select multiple records using a checkbox and click a button to approve selected, which will change the status of the selected items to approved at once. records are like posts.
here is my code:
config/routes:
resources :time_cards do
collection do
get 'management'
put 'approve_multiple'
end
member do
get 'review'
get 'tracking'
patch 'approve_or_reject'
end
end
html:
<%= form_tag({controller: 'time_cards', action: 'approve_multiple'}, method: 'put', id: 'approve_multiple_time_card_form') do %>
<% #time_cards.each do |time_card| %>
<tr>
<% if time_card.status.downcase == 'submitted' %>
<td><%= check_box_tag "time_cards_to_approve[]", time_card.id %></td>
<% else %>
<td> </td>
<% end %>
<td><%= time_card.id %></td>
<td><%= time_card.week_of.to_date.strftime('%B %-d, %Y') %></td>
<td><%= time_card.user.name %></td>
<td><%= time_card.status %></td>
<td><%= output_hours(time_card.time_card_entries) %></td>
<td>
<%= link_to review_time_card_path(time_card) do %>
<% if time_card.status.downcase == 'submitted' %>
<i class="material-icons">edit</i>
<% end %>
<% end %>
</td>
</tr>
<% end %>
<%= submit_tag "Approve Selected", class: 'btn btn-success' %>
<% end %>
controller:
#PUT /time_cards/approve_multiple
def approve_multiple
authorize TimeCard
#time_cards.update_all({status: 'Approved'}, {id: params[:time_cards_to_approve]})
respond_to do |format|
if !#time_cards.errors
format.json { render json: { notice: 'Time cards approved successfully.'} }
format.html { redirect_to redirect_to management_time_cards_path, notice: 'Time cards approved successfully.'}
else
format.json { render json: { error: #time_cards.errors, alert: 'There was a problem approving the time card.'}}
format.html { redirect_to management_time_cards_path, alert: #time_cards.errors}
end
end
end
??? I don't no where it is wrong?
Send these ids to an action like this
Post.where(id: params[:ids]).update_all(approved: true)
params[:ids] is an array of posts' ids
update_all returns the number of the updated records
Ops, I took for granted we were talking about rails but it's never mentioned.

Value is not submitting in using Rails ajax form

I want to store value in db using Rails ajax form but it is not storing anything.Please let me to know where i did the mistake and help me to resolve this issue.
I am explaining my code below.
users/index.html.ebr:
<script type="text/javascript">
$('form').submit(function() {
var valuesToSubmit = $(this).serialize();
console.log('hello')
$.ajax({
type: "POST",
url: $(this).attr('create'), //sumbits it to the given url of the form
data: valuesToSubmit,
dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
}).success(function(json){
console.log("success", json);
});
return false; // prevents normal behaviour
});
</script>
<p><%= flash[:notice] %></p>
<%= form_for :user do |f| %>
<p>
Name : <%= f.text_field :name,placeholder:"Enter your name" %>
</p>
<p>
Email : <%= f.email_field :email,placeholder:"Enter your email" %>
</p>
<p>
Content : <%= f.text_field :content,placeholder:"Enter your content" %>
</p>
<p>
<%= f.text_field :submit,:onchange => "this.form.submit();" %>
</p>
<% end %>
<div id="sdf-puri" style="display:none" >
</div>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
respond_to do |format|
format.html
format.js
end
end
def create
#user=User.new(params[:user])
if #user.save
flash[:notice]="user created"
end
end
end
create.js.erb
$("#sdf-puri").css("display", "block");
$("#sdf-puri").html("<%= escape_javascript (render 'table' ) %>");
$("#sdf-puri").slideDown(350);
create.html.erb
<%= render 'table' %>
_table.html.erb
<table>
<tr>
<th>Name :</th>
<th>Email :</th>
<th>Content :</th>
</tr>
<% #user.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= user.content %></td>
</tr>
<% end %>
</table>
After submit value should display in same index page.Please help me.
Rails has a built in Ajax system, on your form you need to add remote: true
form_for(#user, remote: true) do |f|
This tells rails to submit the form using Ajax under the hood... You don't need all of the script above the form
Your controller already correctly has the line:
responds_to js
So all you would do is have a create.js file in your views/user folder that handled your return Ajax stuff such as appending or fading etc
you need to add remote: true in form tag

ActionMailer looping through nested attributes in Rails

How can I loop through the following output code from the console? Essentially, stories is a nested attribute of an entry and I need to pass "story.content" to a message variable that is used in the email template.
//output in firefox console from new.html.erb
name="message[story_attributes][7][content]"
//new.html.erb This is the form
<% for story in #entry.stories %>
<%= fields_for "message[story_attributes][]", story do |ff| %>
<tr>
<th><%= ff.label(:content) %></th>
<td><%= ff.text_area(:content) %></td>
</tr>
<% end %>
<% end %>
//internal_email.html.erb - ?????
<% for ... in #message.story_attributes %>
?????
<% end %>
If the app is not sending the email, try changing deliver to deliver!
also, make sure that you reinitialize the values in InternalEmail class
class InternalEmail << ActionMailer::Base
def internal_email(message)
#message = message
mail(to: "", subject: "")
end
end

Accessing data through associations

I'm very green when it comes to RoR and am having trouble trying to figure out whether my issue is caused by a problem in my model associations or whether I'm just not using the right syntax to access the data.
A user can have many budgets. Each budget is comprised of multiple detail lines. I thought there wasn't a need for the user id in budget_details since it's captured in budget and so can be inferred through the relationship between the three (maybe?!)
In the budget_details index I want to be able to include the users name; I've got it to work in the 'show' view but not the index.
I did use a scaffold to set these up, so I know there's a lot of crud there, I was just trying to do an example before moving to a new project to do it for real.
The actual error is;
NoMethodError in Budget_details#index
Showing C:/Sites/example1/app/views/budget_details/index.html.erb where line #17 raised:
undefined method `name' for nil:NilClass
I can't see why this fails but the show method works? Is is something to do with the scope? ie show is at the single instance level whereas index is at the 'all' level and so it can't find the data in Users?
Any help much appreciated
Models:
User.rb
class User < ActiveRecord::Base
attr_accessible :email, :name
has_many :budgets
has_many :budget_details, :through => :budgets
Budget.rb
class Budget < ActiveRecord::Base
attr_accessible :budget_name, :user_id
belongs_to :user
has_many :budget_details
Budget_details.rb
class BudgetDetail < ActiveRecord::Base
attr_accessible :amount, :amount_type, :budget_id, :itemname
belongs_to :budget
Controller - budget_details_controller.rb
class BudgetDetailsController < ApplicationController
# GET /budget_details
# GET /budget_details.json
def index
#budget_details = BudgetDetail.all
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #budget_details }
end
end
# GET /budget_details/1
# GET /budget_details/1.json
def show
#budget_detail = BudgetDetail.find(params[:id])
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #budget_detail }
end
end
.....
show.html.erb
<%= notice %>
<p>
<b>Username:</b>
<%= #user.name %>
</p>
<p>
<b>Budget:</b>
<%= #budget_detail.budget_id %>
</p>
<p>
<b>Itemname:</b>
<%= #budget_detail.itemname %>
</p>
<p>
<b>Amount:</b>
<%= #budget_detail.amount %>
</p>
<p>
<b>Amount type:</b>
<%= #budget_detail.amount_type %>
</p>
<%= link_to 'Edit', edit_budget_detail_path(#budget_detail) %> |
<%= link_to 'Back', budget_details_path %>
index.html.erb
<h1>Listing budget_details</h1>
<table>
<tr>
<th>Username</th>
<th>Itemname</th>
<th>Budget</th>
<th>Amount</th>
<th>Amount type</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #budget_details.each do |budget_detail| %>
<tr>
<td><%= #user.name %></td>
<td><%= budget_detail.itemname %></td>
<td><%= budget_detail.budget_id %></td>
<td><%= budget_detail.amount %></td>
<td><%= budget_detail.amount_type %></td>
<td><%= link_to 'Show', budget_detail %></td>
<td><%= link_to 'Edit', edit_budget_detail_path(budget_detail) %></td>
<td><%= link_to 'Destroy', budget_detail, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
In your index.html.erb file:
<td><%= #user.name %></td>
You haven't defined #user in your index action - hence the error.
You can avoid this problem and altogether directly pulling #user in the controller for either action, if just use the association:
<td><%= budget_detail.user.name %></td>
And to avoid the performance hit for doing so (N+1), you can eager-load them in your controller using includes:
#budget_details = BudgetDetail.includes(:user).all
However, this association doesn't yet exist - you will need to add a 'has-one-through' relationship to your BudgetDetail class - the reverse of what you did for your User class.
has_one :user, :through => :budget
To summarize:
You should add a user association to BudgetDetail as 'has-one-through'.
Your controller actions should look like this:
def index
#budget_details = BudgetDetail.includes(:user).all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #budget_details }
end
end
def show
#budget_detail = BudgetDetail.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #budget_detail }
end
end
And in your views don't use #user.name rather:
<%= budget_detail.user.name %>
The error indicates that #user.name errors because #user is nil.
In your controller you currently seem to fetch:
def index
#budget_details = BudgetDetail.all
#users = User.all
end
def show
#budget_detail = BudgetDetail.find(params[:id])
#user = User.find(params[:id]) # THIS WOULD MEAN THAT A USER HAS THE SAME ID AS THE BUDGET_DETAIL
end
As the index action fetches the variables for the index template, you see that you aren't fetching any #userthere, just an #usersvariable that holds all users.
Instead, you should remove the user fetching in both actions, and fetch them in the view through the budget_detail.user association.
def index
#budget_details = BudgetDetail.all
end
def show
#budget_detail = BudgetDetail.find(params[:id])
end
show.html.erb
<p>
<b>Username:</b>
<%= #budget_detail.user.name %>
</p>
<% #budget_details.each do |budget_detail| %>
<tr>
<td><%= budget_detail.user.name %></td>
...
</tr>
<% end %>

Resources