All the examples of Kaminari I have seen only have 1 variable in the controller action.
But here is my example:
def index
#draft_item = #account.draft_item # only ever one
#in_force_item = #account.in_force_item # only ever one
#historical_items = #account.lo_items.historical # many of these
respond_to do |format|
format.html
end
end
These are all displayed in a table on the view, which I want to paginate. Do I need to combine these into 1 array first in the index action?
My loop on the view is like this:
<% [#in_force_item, #draft_item, #historical_items].compact.flatten.each do |lo_item| %>
then I have code like:
<% if lo_item == #draft_item %>
Is this possible and still be able to call the line above>?
Thanks to the answer below, I was able to do it like this:
#total_items = Kaminari.paginate_array([#draft_item, #in_force_item, #historical_items].compact.flatten).page(params[:page]).per(10)
It all had to be on one line for it to work, unlike the answer below which had it split across two lines.
It is. Kaminari has paginate_array
#draft_item = #account.draft_item # only ever one
#in_force_item = #account.in_force_item # only ever one
#historical_items = #account.lo_items.historical
#total_items = [#in_force_item, #draft_item, #historical_items].compact.flatten
Kaminari.paginate_array(#total_items).page(params[:page]).per(10)
Then
<% #total_items.each do |lo_item| %>
<% end %>
<%= paginate #total_items %>
Related
I'm building a Rails app where I have individual entries called films. I would like to display the latest entry's link on the homepage (separate controller) and I'm struggling to make it work.
My films_controller.rb is as follows (excerpt):
def show
#film = Film.find(params[:id])
end
My home_controller.rb only has the following:
def index
end
And my view file (index.html.erb) has the following:
<%= link_to #film.last.filmTitle, film_path(#film) %>
I'm getting the following error:
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
With the #film.find(params[:id]) highlighted.
Thanks!
The last method:
Find the last record (or last N records if a parameter is supplied). If no order is defined it will order by primary key.
source
You can add a #last_film instance variable in your index controller and use it in the view.
def index
#films = Film.all
#last_film = Film.last
end
and in your index.html.erb
<%= link_to #last_film.filmTitle, film_path(#last_film) %>
The index method need something, currently, it didn't connect with ActiveRecord like model or table, that's why
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
So if you need to show recent posts in the index then you could something like this
def index
#films = Film.limit(10).order(created_at: :desc) #=> or you can use id
end
it will show last 10 records, for this in the index.html.erb like this
<% #films.each do |film| %>
<%= link_to film.filmTitle, film_path(film) %>
<% end %>
In the other hand if you need to show only one post which is the last then you should modify this query like this like limit(10) to limit(1) or you can use use the last method like this
def index
#film = Film.last
#or
##films = Film.limit(1).order(created_at: :desc) #=> or you can use id
end
if you use this #film = Film.last then your index file will like this
<%= link_to #film.filmTitle, film_path(#film) %>
otherwise, you need to use each method which describes before.
got a super quick question. I'm still new to rails and tried following these two questions but they didn't work for me:Why does Array.to_s return brackets? and ruby 1.9 how to convert array to string without brackets.
I'm trying to show the last message and the date in which it was sent out in my chatroom application. I am able to get the results using this code, but it has brackets around it and I would like to have those brackets removed. Any help here would be amazing, I've attached a screenshot as well. Thank you so much!
Show.html.erb
For the Date:
<%= chatroom.messages.last(1).pluck(:created_at) %>
For the Last Message in Chatroom:
<%= chatroom.messages.last(1).pluck(:body) %>
DirectMessages Controller
class DirectMessagesController < ApplicationController
before_action :authenticate_user!
def show
users = [current_user, User.find(params[:id])]
#messageduser = User.find(params[:id])
#chatroom = Chatroom.direct_message_for_users(users)
#chatroomall = current_user.chatrooms
#messages = #chatroom.messages.order(created_at: :desc).limit(100).reverse
#messagelast = #chatroom.messages.last(1)
last_message = #chatroom.messages.last
render "chatrooms/show"
end
private
def chatroomuserlocator
#chatroomlocator = Chatroom.find(params[:chatroom_id])
end
end
Try this:
<%= chatroom.messages.last.created_at %>
And this:
<%= chatroom.messages.last.body %>
Keep in mind that pluck returns an array, so that would explain your brackets.
I don't think you need pluck here since you are just accessing an attribute on a single item.
If you're not too worried about memory usage, you can fetch the whole object and only access the fields you want.
<%= chatroom.messages.last.created_at %>
<%= chatroom.messages.last.body %>
You can assign the lookup to a value, so it doesn't run twice:
last_message = chatroom.messages.last
Then you can access the attributes efficiently:
last_message.created_at
last_message.body
If you are interested in limiting the attributes or last_message, use select:
last_message = chatroom.messages.select(:created_at, :body).last
Putting it all together:
<% last_message = chatroom.messages.select(:created_at, :body).last %>
<%= last_message.created_at %>
<%= last_message.body %>
I previously built an app (my first rails app) designed to display a single quote from the db at random on screen (and a different one on each refresh). I'm now aiming to refactor that app to display all of the quotes (paginated, I guess) in a grid format.
The catch is that I'm uncertain how to pull all of the quotes to display on the page instead of just one at random. In the controller, I previously had:
def index
#quote = Quote.order("RANDOM()").first
end
Would it be something like this?
def index
Quote.each do
#quote = Quote.order("RANDOM()")
end
end
Type this in your controller:
def index
#quotes = Quote.order("RAND()").all
end
In your view type this:
<% #quotes.each do |quote| %>
<%= quote.id
<%= quote.X <---------REPLACE X for the column to show
<%= quote.X <---------REPLACE X for the column to show
<% end%>
In your controller
def index
#quotes = Quote.order("RANDOM()")
end
Then in your view
-#quotes.each do
That should do the trick
Converting another app from Rails 2 to Rails 3 - in one of my views I have this code:
<%fields_for "order[commission_attributes][]", commission do |f|%>
This is driven from the controller action below:
def edit
#order = Order.find(params[:id],:include=>[{:orderitems=>:item_schedules}, :memberids ],:order=>"orderitems.updated_at DESC")
#active_order_iems = []
#inactive_order_items = []
#order.orderitems.each do |oi|
oi_active = nil
oi.item_schedules.each do |is|
if (is.end_date > Date.today)
oi_active =true
break
end
end
#active_order_iems << oi if !oi_active.nil?
#inactive_order_items << oi if oi_active.nil?
end
#commissions = #order.commissions.find(:all)
#ordertypes = Ordertype.find(:all, :order=>"description")
#salesreps = Salesrep.find(:all, :order=>"fullname")
#customers = Customer.find(:all, :order=>"company_name")
#memberids = Memberid.find_all_by_customer_id(#order.customer_id)
#products = Product.find(:all, :include=>[:items],:order=>["products.description"])
#partners = Partner.find(:all, :order=>"company_name")
end
def get_reps
#salesreps = Salesrep.find(:all,:order=>"fullname")
#commission = Commission.new
render :partial=>'commission'
end
In my 'order' model I then have this:
def commission_attributes=(commission_attributes)
commission_attributes.each do |attributes|
if attributes[:id].blank?
commissions.build(attributes)
else
commission = commissions.detect{|t| t.id == attributes[:id].to_i}
commission.attributes = attributes
end
end
end
This works in rails 2, however in rails 3 I get the error below:
#order[commission_attributes]' is not allowed as an instance variable name</code></pre>
I can't seem to work out what the problem is, or how to work around this issue.. any help is very appreciated.
Andrew
The fields_for method only takes objects or symbols. It's hard to give a specific solution without more code but something like this might work:
<%= form_for #order do |form| %>
...
<%= fields_for #order.commission do |commission_form| %>
Read up on it here: http://apidock.com/rails/v3.0.0/ActionView/Helpers/FormHelper/fields_for
Another alternative is
<%= f.fields_for :commission, commission do |commission_form| %>
This should cause then submit to trigger commission_attributes= instead of messing with another model directly, and by supplying the object you can populate the form with said object.
But this is just another method worth mentioning. Here's the doc fields_for#Nested Attributes
From my controller I am passing two instance variables #events = Event.all and #images = Images.all. In the view I begin by iterating through #events.each do |event| and within this block is the line img = #images.shift yet when I try to access any method of img such as img.filename I get an error that img is nil but I have checked and am certain that #images is populated correctly. If I simply output img.class I receive the correct class, Image, but cannot access any of it's methods.
What am I doing wrong or why is this way of pulling instances from an array incorrect?
I know there are other ways of going about this but this specific problem confounds me and I would really like to understand why this doesn't work. Thanks.
#Structure of the model is
Image
-filename :string
-date :datetime
-caption :text
-source :string
#Controller
def index
#events = Event.all
#images = Image.all
end
#index.html.erb
<% #events.each do |event| %>
... code that works ...
<% if count==1%>
<% img = #images.shift %>
<div><%= img.filename %></div>
<% end %>
<% end %>
#For testing purposes I changed
<% img = #images.shift %>
<div><%= img.class %></div>
#output is Image
The problem might occur when there is more events then images. Because every time an iteration goes through #events array then the #images are shifted and is taken the next element from the array. So when you have for example 4 elements in #events and only 3 in #images then at 4th iteration there is taken 4th element from #images and this is nil
There are two cases when the return value of Array#shift becomes nil.
The leftmost element of the array is nil.
The array is empty (= []).
It is probably either of the cases.