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 %>
Related
I am building a rails app where I have a museums page which has a feature where it displays the museum with the most exhibits. The problem is that when there are no exhibits added to the db it gives an undefined method 'museum_name'. So the problem I have is I am not sure what would be the best way to make a check that would still allow me to access the page if there are zero exhibits?
Museums controller:
def index
#museums = Museum.all
most_exhibits = Exhibit.most_exhibits
most_exhibits.each do |museum|
#top_museum = MuseumsHelper.get_museum_name(museum.museum_id)[0]
end
Helper class method being used:
def self.get_museum_name(museum_id)
Museum.where(id: museum_id)
end
Display in views:
<%= #top_museum.museum_name %>
The best way to do it depends on how you want it to be. I think the ideal solution for yours is to check if/else then show the content accordingly:
<% if #top_museum.present? %>
<%= #top_museum.museum_name %>
<% else %>
<span>Nothing to display</span>
<% end %>
Or using try <%= #top_museum.try(:museum_name) %> or if you have ruby 2.3.0 or newer you can use safe navigation operator <%= #top_museum&.museum_name %> (Read more).
You could use try in your helper, that way it tries the query, if it fails then it returns nil
def self.get_museum_name(museum_id)
Museum.try(where(id: museum_id))
end
Ref: https://apidock.com/rails/v3.2.1/Object/try
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.
I want to know how to get a specific record from an object example
#user = User.all
In index.html.erb, I want to show only the record that in the 3rd order , I try, but this gives me all the records. :
<% #user.each do |u| %>
I found this :
<% #user.find{|b| b.id == 1}%>
<%= #service.full_name%>
But didn't work and I don't know how to use it right in index.html.erb
Also you can take array element directly in template. For reason – if you need all another users to
<div class="super-user">
<%= #users[3].name %>
</div>
<div class="other-users">
<% #users.each do |u| %>
Destroy Him!
<% end %>
</div>
If you don't need all another users, prefer to don't fetch them all. Use find or find_by methods e.g.
#user = User.find(4) # finds user by id=4
or
#user = User.find_by(name: 'user', admin: true) # finds by hash arguments
or even
# fetch direcly 3-th user from database
#user = User.order(:id).limit(1).offset(2).first
http://guides.rubyonrails.org/active_record_querying.html
http://ruby-doc.org/core-2.3.1/Array.html
You can also just write
#user = User.all.third
Boris is right though just returning all the records is a bad practice. It may not be noticeable at this point in time but as the amount of User records in your database grow this query will get proportionally slower. So the better option is
#user = User.third
I am trying to create associated models with Rails. My models are Financial which have many documents and Document which belongs to Financial. A working code when creating the associated model could be
def create
#financial = Financial.find(2)
#document = #financial.documents.create(document_params)
...
end
In my view I have a form which looks like this to select the right Financial
<%= form_for Document.new do |f| %>
<%= f.collection_select :financial_id, Financial.all, :id, :description %>
<%= f.submit %>
I do see the right parameters being transferred in the log when I submit the form
"financial_id"=>"3"
So I figured I would just need to change the initial code to:
def create
#financial = Financial.find(params[:financial_id])
#document = #financial.documents.create(document_params)
...
end
but I get a "Couldn't find Financial with 'id'=". I have tried other things including:
#financial = Financial.find_by(id: params[:financial_id])
Without much success. Could anyone give me the appropriate syntax please? Thanks.
Couldn't find Financial with 'id'=
Because, the params that are submitted are actually inside document hash. So params[:financial_id] won't work. Instead you need to use params[:document][:financial_id]
def create
#financial = Financial.find(params[:dcument][:financial_id])
#document = #financial.documents.create(document_params)
...
end
I have difficulties with ruby on rails syntax.
I got this error
First argument in form cannot contain nil or be empty
class PersonalsController
def index
end
def create
#personal = Personal.new
end
def new
#personal = Personal.new
end
def show
#personal = Personal.find([:id])
end
end
index.html.erb
<%= form_for #personal do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title %>
<%= f.submit %>
<% end %>
the value of #personal is nil that's why you are getting error.
Change you code like this
def index
#personal= Personal.all
end
form_for is helper method
check with this link form_helper
The error is generated since #personal was not set in the controller. So either you add a #personal = Personal.new to the index method, or set it to a specific database entry, e.g., #personal = Personal.find(1)
However, it seems strange that you have a form displaying a single record in the index view.
More likely, you want to have the form in your new or edit views (in the former case you typically use new, while in the latter case you would use the find method to find a specific record and let the user edit it).
In the index method, you usually use the controller to select a group of records (e.g., #ps = Personal.all to get all the records) and iterate over them in the view (#ps.each do |person| .... end)
P.S. The show method should probably use Personal.find(params[:id]) instead of Personal.find([:id])