Rails 4 error: The scope body needs to be callable - ruby-on-rails

I'm trying to make an app in Rails 4.
I have an industry model.
I'm trying to make an index of industries, and list them alphabetically.
I have an industry.rb with:
scope :alphabetically, order("sector ASC")
I have an index controller with:
def index
#industries = Industry.alphabetically
end
In my index view, I have:
<% #industries.each do |industry| %>
<tr>
<td><%= image_tag industry.icon.tiny.url %></td>
<td><%= industry.sector %></td>
<td><%= link_to 'Show', industry %></td>
<td><%= link_to 'Edit', edit_industry_path(industry) %></td>
<td><%= link_to 'Destroy', industry, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
When I try this, I get this error:
ArgumentError in IndustriesController#index
The scope body needs to be callable.
How do I make a scope 'callable'?

As per the error message, the scope's body needs to be wrapped within something callable like a Proc or Lambda. Like this:
scope :alphabetically, -> {
order("sector ASC")
}
This ensures the contents of the block is evaluated each time the scope is being used.
So, if you change your scope as shown above, it should work and fix your problem.

Related

How can i get User name in a table where user_id is used as foreign key

I am using Devise gem for user Authentication. User id is as foreign key in article table
How can i get writer name through User_id in a view Show_article.html.erb
I can access user_id in show_article.htmlerb
I have tried to make a custom function in article controller but could not get the desired output
your Article model should look like this:
class Article << ActiveRecord::Base
belongs_to :user
#....some more lines
end
your User model should look like this:
class User << ActiveRecord::Base
has_many :articles
#....some more lines
end
and your show.html.erb should say:
#....your rest of code
<%= #article.try(:user).try(:name) %>
#....your rest of code
This will skip user name if you article doesn't have any user. It looks like your article doesn't have user_id or you haven't defined your relations correctly.
It might be the case that some of your article do not have any user. so
you can do
<%= #article&.user&.name %> in show page
and in the index page
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= article&.user&.name%></td>
<td><%= link_to 'Show', article_path(article) %></td>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Delete', article_path(article),
method: :delete,
data: { confirm: 'Are you sure you want to delete this article?' } %></td>
</tr>
<% end %>
but make sure you have ruby 2.3.0 or higher

Using link_to to trigger an increment action in a controller

I have been butting my head against a wall trying to figure this sucker out.
Basically, I have a 'Quote' model that has 3 fields - content, author and votecount.
Votecount is an integer, and I want to be able to add a vote (increment) from the quotes/index view using a link. This is what I've come up with so far:
views/quotes/index.html.erb
<% #quotes.each do |quote| %>
<tr>
<td><%= quote.content %></td>
<td><%= quote.author %></td>
<td><%= quote.votecount %></td>
<td><%= link_to 'Show', quote %></td>
<td><%= link_to 'Edit', edit_quote_path(quote) %></td>
<td><%= link_to 'Upvote', quote_upvote_path(quote) %></td>
<td><%= link_to 'Destroy', quote, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
quotes_controller.rb
def upvote
#quote = Quote.find(params[:id])
#quote.increment!(:votecount)
redirect_to quotes_path
end
Routes.rb
resources :quotes do
get 'upvote'
end
And this is the error message I receive:
ActiveRecord::RecordNotFound in QuotesController#upvote
Couldn't find Quote with 'id'=
So the action isn't able to find the quote ID, however it's in the actual URL so I'm not sure what I'm bollocksing up here!
Define the upvote action as a member action:
resources :quotes do
get 'upvote', on: :member
end
See the Rails routing documentation for more information.

How to update multiple records with rails 4 & mongoid

I want to model student's attendance, i am following railscast.com/165-edit-multiple-revised i follow Ryan's first approach and try to use it with mongoid. My modified code is as follows but it does not update multple records, well it even doesnt update any of the record. sounds like mongoid does not found any Student with id of an array. plz see the code and let me know what i am doing wrong.
# config/routes.rb
resources :students do
collection do
put :attendance
end
end
# model/student.rb
class Student
include Mongoid::Document
field :name, type: String
field :present, type: Mongoid::Boolean
end
# controllers/students_controller.rb
def attendance
Student.where(id: params[:student_ids]).update_all(present: true)
redirect_to students_url
end
# views/students/index.html.erb
<% #students.each do |student| %>
<tr>
<td><%= check_box_tag "student_ids[]" , student.id %></td>
<td><%= student.name %></td>
<td><%= student.present %></td>
<td><%= link_to 'Show', student %></td>
<td><%= link_to 'Edit', edit_student_path(student) %></td>
<td><%= link_to 'Destroy', student, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
if i change the code in controller as follows than it works but i am not satisfied with this code. is there any other way around or i am doing something wrong?
# controllers/students_controller.rb
def attendance
params[:student_ids].each do |student_id|
Student.where(id: student_id).update_all(present: true)
end
redirect_to students_url
end
If you want to fetch a set of student, you should try the in operator. Try this:
def attendance
Student.where(:id.in => params[:student_ids]).update_all(present: true)
redirect_to students_url
end
What do you think?

URL link gives dot instead of slash

in my route.rb I have this
Rails.application.routes.draw do
resources :cars do
resource :payments
end
end
However, in my destroy link for payments. the URL generated is
http://localhost:3000/cars/9/payments.11
Below is my code.
<% #car.payments.each do |p| %>
<tr>
<td><%= p.date %></td>
<td><%= p.profit %></td>
<td><%= p.remark %></td>
<td><%= link_to 'Delete', car_payments_path(#car, #p) ,
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
Please advice. Thank you in advanced.
Looks like this is a pluralization error.
Try
cars_payment_path
instead of
car_payments_path
To delete a payment in a car, the route should be a member route , call it like this:
car_payment_path(#car, #p)
car_payments_path(..) was a collection route of payments.
Suggest you to test at console like this:
app.car_payment_path(Car.first, Car.first.payments.first)

Only displaying certain entries from a log based on id

I have a log in my webapp where you can input hours, and when you input your hours it automatically takes the account you are logged into(built using devise and cancan), and finds what your user_id is and tacks it on to an hour log.
Now what I cant seem to find out is how I can go about making it so that it only displays logs with your user_id. Is there a way to do this in the model or controller instead of the view?
This is the view code as of now.
<% #time_sheets.each do |time_sheet| %>
<tr>
<td><%= time_sheet.user_id %></td>
<td><%= time_sheet.day %></td>
<td><%= time_sheet.hours_worked %></td>
<td><%= time_sheet.minutes_worked %></td>
<td><%= link_to 'Show', time_sheet %></td>
<td><%= link_to 'Edit', edit_time_sheet_path(time_sheet) %></td>
<td><%= link_to 'Destroy', time_sheet, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
It shows the logs of everyone in the system instead of just that user.
Devise gives you a helper method named current_user. In your controller you can filter by user ID using the current_user.id. Like so:
#time_sheets = TimeSheet.where(:user_id => current_user.id).all
And that will give you only the currently logged in user's time sheets.

Resources