BigL
BigL

Reputation: 89

ROR: Search by Username and display their posts

I am learning Ruby on Rails and have a search form set up and its working. On the pins index view I can search for pins(posts) by their title. However if I wanted to search by Username which is not in the pins table and display the results on the Pins index page how would I do this? How do I access an attribute from a different table? (Sorry for the newbie attempt at explaining my issue)

Pins controller

 def index
    @pins = Pin.search(params[:term])
end

Pin Model

def self.search(term)
  if term
    where('description LIKE ?', "%#{term}%")
  else
     order('id DESC') 
  end
end

_search.html.erb

<%= form_tag(pins_path, method: :get) do %>
  <%= text_field_tag :term, params[:term] %>
  <%= submit_tag 'Search', description: nil %>
<% end %>

Upvotes: 0

Views: 336

Answers (2)

basiszwo
basiszwo

Reputation: 620

Assuming you have set up something like

class User < ApplicationRecord
  has_many :pins

  # the username is stored in the attribute 'username'
end

class Pin < ApplicationRecord
  belongs_to :user
end

you may do the following

# PinsController
def index
  terms = params[:term]
  username = params[:username]

  @pins = Pin
  @pins = @pins.where("description LIKE '%?%'", term) if term
  @pins = @pins.includes(:user).where("users.username LIKE '%?%'", username) if username

  # you may want to sort by id anyway
  @pins = @pins.order('id DESC')  
end

Note that I put the code straight to the controller for brevity. You may refactor this to use your search method in pin model.

# _search.html.erb
<%= form_tag(pins_path, method: :get) do %>
  <%= text_field_tag :term, params[:term] %>
  <%= text_field_tag :username, params[:username] %>
  <%= submit_tag 'Search', description: nil %>
<% end %>

In case you want to do some more searching and filtering you may have a look at the ransack gem although I think you're going the right path in trying to figure this out yourself.

Although those railscasts episodes are from the past I think they are applicable to the current rails versions. Anyway one can get the point from them

Another good resource is gorails.com (not affiliate in any way!!). I can highly recommend them as a resource for learning

Upvotes: 1

max
max

Reputation: 102036

Provided you have an association between User and Pin

class User
  has_many :pins
end

class Pin
  belongs_to :user
end

You can join :user from Pin and set conditions on the association:

Pin.joins(:user).where('users.username ? AND awesome = ?', 'Max', true)
# or the preferred method
Pin.joins(:user).where(user: { username: 'Max', awesome: true })

Note that we use users.username and not user.username when writing a SQL string you're specifying the table name - not the association.

To search for pins based on the username you could do:

def self.by_username(term)
  joins(:user).where('users.username LIKE ?', "%#{term}%")
end

Upvotes: 0

Related Questions