Dusty Boshoff
Dusty Boshoff

Reputation: 1061

Ruby on Rails Find a String in DB

please don't shout... I'm trying to run a search query to find the Firstname in the database, basically trying to find a specific user then show that user.

What works in the console is Client.where but I can't seem to get this to work in the controller.

irb(main):001:0>client = Client.where("name = 'Dusty'")
Client Load (0.4ms)  SELECT `clients`.* FROM `clients` WHERE (name = 'Dusty')

What I have is.

A View 'index.html.erb':

<%= form_for :find_it do |n| %>
   Name: <%= n.text_field :text, :cols => "30", :rows => "1" %></br>
<%= n.submit "Find" %>

And a Controller Method in clients_controller.rb:

def find_it
  @post = Clients.all
  @post = Client.where("name = ", params[:find_it])
  @post = Client.find(params[:id])
end

Any assistance would be appreciated.

Upvotes: 1

Views: 1392

Answers (3)

Lucas
Lucas

Reputation: 2627

There are several ways to do that:

# with old hash syntax (all ruby versions)
@clients = Client.where(:name => params[:find_it])

# with new hash syntax (ruby 1.9)
@clients = Client.where(name: params[:find_it])

# with text query
@clients = Client.where('name = ?', params[:find_it])

All of them are equivalent.

Code @post = Client.all assigns variable @post with all clients from database and then you reassign it two times with completely different values. In the end your variable @post is assigned with Client record with id equals to params[:id] and this is what will you get in a view.

Also in general you don't have to use all method. Notice that:

Client.where(name: params[:find_it]).all.class
# => Array
Client.where(name: params[:find_it]).class
# => ActiveRecord::Relation

It means that you can query ActiveRecord::Relation with other querying methods i.e.

@clients = Client.where(name: params[:find_it])
@favourite_clients = @clients.where(favourite: true)

Rails will know what to do (it won't process ActiveRecord::Relation until it has to do something with it, i.e. while iterating result in a view), so you would want to add all only when you really need array in controller.

You should also consider using more meaningful variables names like @clients instead of @post.

When it comes to whole solution it should be more like:

# view
<%= form_for :find_it, :url => find_client_path do |n| %>
  Name: <%= n.text_field :text, :cols => "30", :rows => "1" %></br>
  <%= n.submit "Find" %>
<% end %>

Take a look at form_for documentation. You can find out that your text is not params[:find_it], but params[:find_it][:text].

You have to provide :url option with path to your find_it action.

If you want to show results on index view, you can do it like:

# view
<%= form_for :find_it do |n| %>
  Name: <%= n.text_field :text, :cols => "30", :rows => "1" %></br>
  <%= n.submit "Find" %>
<% end %>

# controller
def index
  @clients = Client.scoped
  @clients = @clients.where(:name => params[:find_it][:text]) if params[:find_it]
end

Upvotes: 3

shweta
shweta

Reputation: 8169

replace

@post = Client.where("name = ", params[:find_it])

with

@post = Client.where("name = ?", params[:find_it])

Upvotes: 2

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230386

Your syntax is a bit off. Use hash-style conditions:

def find_it
  @post = Client.where(:name => params[:find_it])
  # @post = Client.find(params[:id]) # why is this line here? It overwrites previous results
end

Upvotes: 4

Related Questions