Ruby on Rails controller order with strings - ruby-on-rails

So I'm trying to organize one of my views so that the articles of my website are listed by the name of the title. For example some of my articles are named "article pt.1, history pt.2, society pt.1, etc". I do have them sorted correctly using this line of code in the Articles controller
def index
#articles = Article.order(:user_id)
end
It does work using the user id, but if I wanted to add another category and have them in alphabetical order, I would need to update the user id of each article which is not practical as they number a little over 200 in the database. What I would like to is somehow take a partial of the article title and sort each one like I am with the user_id field. This way I can sort each one using the string partial such as "article" from "article pt.1"
Thank you for reading and have a wonderful day!

Why not just sort by the title? Assuming you have a column in your articles table called title:
For alphabetical order
def index
#articles = Article.order(:title)
end
For reverse alphabetical order
def index
#articles = Article.order(title: :desc)
end
If you really want to just sort by a substring of the title. You'll have to add a new column to the articles table (called slug in this example):
rails g migration AddSlugToArticles slug:text
rails db:migrate
Then you'll have to update the slug field of every record
Article.all.each do |article|
new_slug = #your code to generate substring here
article.update(slug: my_string
end
then order by slug:
def index
#articles = Article.order(:slug)
end

First of all, it is not very clear about the output that you want, but based on assumption and the description mentioned in the post, it seems like you want to sort the string field not based on whole value but based on substring.
It is better to use the order to get the strings alphabetically sorted.
#articles = Article.order(:title)
And it will also serve the purpose as it will first match the first alphabet of each string and also handle null values at the same time.
Why write a custom logic if the purpose is fulfilled by an already defined method.

I was able to do it using the sort function instead of order using the :title field on the articles controller.
def index
#articles = Article.sort(:title)
end

Related

active_admin config.sort for two columns

I have an active_admin table called shows that acts of a list of rsvps for bike riders and bike shows that the riders will compete in. The following code correctly sorts the table alphabetically by rider_last_name:
config.sort_order = 'rider_last_name_asc'
Now when a rider is attending multiple bike shows, I want the table to first sort by rider_last_name and then within that rider sort by an attribute of shows called start_time. start_time is a DateTime. According to this stackoverflow article, the following should work:
config.sort_order = 'rider_last_name_asc, start_time_asc'
but it doesn't. In fact, it undoes the sorting by rider_last_name. How do I sort by both columns?
You may try refine apply_sorting method for collections, like this:
controller do
def apply_sorting(chain)
params[:order] ? chain : chain.reorder(rider_last_name: :asc, start_time: :asc)
end
end
ActiveAdmin suggests overwrite the find_collection method, which returns an ActiveRecord::Relation. But I prefer add the order to it's output.
ActiveAdmin.register Show do
controller do
def find_collection(options = {})
super.reorder(rider_last_name: :asc, start_time: :asc)
end
end
...
end
Although it works, this overwrite the user option of click on a column.
Alternative
You can do the same with scoped_collection, which is called at the start of find_collection, but it does not work unless you add active_admin_config.sort_order = '' to the controller. This way:
controller do
active_admin_config.sort_order = ''
def scoped_collection
super.reorder(rider_last_name: :asc, start_time: :asc)
end
end
Now, if we want to reorder before and, after that take care of the user params (and do not overwrite them). This is the way.
Note: I did use active_admin_config.sort_order and not config.sort_order.
Also, the sort_order option, ends as a param of OrderClause.new call, which expect for only one sort field, see here and here.
you can try to pass an array to it as such:
config.sort_order = [:rider_last_name_asc, :start_time_asc]

Does Rails Auto-Assign ID's?

I'm trying to sort my users in my controller, and I wanted to sort them by id number. My question is, does rails automatically assign orders an id when they are created, or do I need to add that to the create function in my create action in my controller? For example, can I say this:
def index
#users = User.all.order(:WHAT TO PUT HERE???????)
end
Would I put :id in the space? If I did so, would I need to define id somewhere else or is this something ruby does on the back end?
In most cases Rails would return you records sorted by id. But you should not rely on Rails as sorting is database-specific.
To explicitly add sorting by id you should use:
def index
#users = User.order(:id)
end
Id is automatically added, you don't need to declare it anywhere.
Rails only helps you create the table via migrations. When a migration creates a table it automatically adds the id column as a primary key set to auto increment. So why you create records it's actually the database that adds the id, or as aforementioned, it auto increments it +1 from the last id. Therefore, when you use ActiveRecord to create a record you don't need to specify an id.
Now for your main question: you can pass the name of the column to the order method when you want to sort ascending by that column. You don't need to call all though.
So just do this:
User.order(:id)
That will sort from lower ids to higher. To do the opposite:
User.order("id DESC")
This will give your the most recently created records first by sorting from higher ids to lower.
If you want to sort User by ID
#users = User.order(:id) #ASC default
#users = User.order('id ASC') #ASC explicit
#users = User.order('id DESC') #DESC explicit
...and never forget the User.order('-id') unary minus shortcut...

Rails 4: Displaying a table of a collection of items, sorted by various item attributes?

So I have a CareerEntry model that has the following attributes: name, job_category, company, group, location, year, full_intern, and it represents the job offers that people have received. full_intern is a string that is either "internship" or "full-time", and represents what the type of the job offer is. All CareerEntries will be created by an Admin interface, so it is essentially acting as a standalone model. This is my question: given a bunch of CareerEntry objects, I want to display a table to display on my careers page (which has an action in a PagesController).
I want the table to be sorted according to multiple attributes. I want each year to be its own section in the table, then within each year, I want the internship entries grouped together and the full-time entries grouped together. Then, within these groupings, I want each job_category to be its own section (job_categories comprise of things like 'Investment Banking,' or 'Technology.')
A very good example of what I'm going for is shown under the "2013" tab in this link.
What is the best way to go about achieving this? I know that in the careers action definition of my PagesController, I could have:
class PagesController < ApplicationController
def careers
#careerentries = CareerEntry.order(:year => :desc, :fullintern => :asc, :job_category => :asc)
end
end
But this would simply return all the entries in the order that I want, and would not allow me to place headers and dividers to separate, say, the job_categories.
Is there any easier way of achieving what I'm looking for?
Perhaps you're looking for .group_by?
Group By
From the link you gave, it looks like you want to group your results by year, like this:
#careerentries = CareerEntry.order(year: :desc, fullintern: :asc, job_category: :asc)
#entries_by_year = #careerentries.group_by { |entry| entry.year }
This gives you all the data, ordered to your specs. You can then sort through it, using the group_by method:
#entries_by_year.each do |entry|
entry.name
end
You could then work this into your table
Good reference Group posts by Year - Rails

Ruby on Rails SQlite 3 database query

I have been looking online about how to do queries for Ruby on Rails and I can find information how to build the query but not where I put the physical code. I am very new to Ruby on Rails.
I have one database called story and it has the title and content columns that I made. I have a page that is used to input the title and content and then stored into the database and then I have a page which displays all contents of the database but I do not understand how to do a query to find let's say, "a record that has a content or title that contains a certain word or phrase"
<%= #story.content %>
So i understand that displays the content on the screen, do i just do the same thing for queries?
In rails active records are used not direct sql queries
here's a good link that explains it ......
http://guides.rubyonrails.org/active_record_querying.html
For example lets say you have post model and you want
Index all posts then use
#posts = Post.all
you want to show specific post ,find it by id
#post = Post.find(params[:id])
create a new post by
#post = Post.new
As per your query, In your controller Write like
#stories = Story.where("stories.content IS NOT NULL") #Records those has a content
#stories = Story.where("stories.title LIKE%a_certain_word_or_phrase%") # Records that contains a certain word or phrase
If you want to pick up only one recoed from the databse you can user .first .last for example
#sotory = Story.where("stories.content IS NOT NULL").first #first item which has content
#sotory = Story.where("stories.content IS NOT NULL").first #last item which has content
You can also find by id like
#story = Story.find(1) # finds the record with id = 1
and so on ......
I think you need a good tutorial.As you are a newbie please checkout Ruby on Rails Guides: Active Record Query Interface

Rails 3 Joins -- Select only certain columns

Below is a relationship between Comments and a user. Each comment has one user so I'm building out a join in the code below.
I was wondering how to build this code to only include specific columns in the join. I don't need all of the user information. Just the first_name. Any suggestions.
Current Code:
#comments = Comment.where(:study_id => #study.id).joins(:user)
You could use something like this:
#comments = Comment.joins(:user)
.select("comments.*, users.first_name")
.where(study_id: #study.id)
Extending Aldo's answer to show a way to retrieve the resulting foreign column value.
#comments = \
Comment\
.joins(:user)
.select("comments.*, users.first_name as users_first_name")
.where(study_id: #study.id)
# Now it's stored on each comment as an attribute, e.g.:
puts #comments.first.read_attribute(:users_first_name)
puts #comments.first.attributes['users_first_name']
# Note that inspecting the comment won't show the foreign data
puts #comments.first.inspect # you won't see user's first name output
You could also declare users_first_name as an attrib on the comment with attr_accessible. I don't think there's any magic way to automatically set it, but you could easily do so yourself in a post-select loop.

Resources