pyfl88
pyfl88

Reputation: 1710

Action show to find value from hash instead of id

I am still learning rails and have done a lot of readings, but I am not very clear about how params, 'show' actions work yet.

For example we have UsersController, 'index' action is showing all the users with the code @user = User.all, and 'show' action is looking into each users, by using the code @user = User.find(params[:id])

I understand that they are all from the database, where User is a model.

However in my scenario, what if the data I am showing in views, doesn't go through database, instead in the 'index' action it is something like this - @user = [{name => "alex"}, {name => "peter"}, {name => "john"}]

and in my 'show' action, how can I write the code so that it finds the users by name?

Upvotes: 2

Views: 312

Answers (3)

Chakreshwar Sharma
Chakreshwar Sharma

Reputation: 2610

In show action , we search the user specific record not all.

So , we have to provide some unique identifiers as parameters to find the specific record.

For eg. Your view should be similar to the params we are passing as below:

<% @user.each do |user| %><br>
  <%= link_to user.name, user_show_path+"?name="+user.name %><br>
<% end %><br>

In show action , write the code

def show
  @user = User.find_by(:name => params[:name])
end

Also in routes.rb , write the below code:

get 'users/:name', to: "users#show"

For the above solution, make sure that name field will be unique.

Upvotes: 2

Richard Peck
Richard Peck

Reputation: 76784

My original question is that if it is possible for 'show' action not to go through database

Sure.

Your show action can be the following if you wanted it to:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def show
      @user = "me"
   end
end

You really don't have to do anything specific in your application, Rails is just a framework and has certain conventions if you want it to work efficiently.

What you're asking is if you can populate your @user object from a third party set of data...

... Yes you can ...

The way to do it would be in the model, not the controller:

#app/models/user.rb
class User < ActiveRecord::Base
   # populates from Hash
end 

You'd then be able to populate the data in the controller from the model again:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def show
      @user = User.__________ #-> pull from your hash
   end
end

finds the users by name

That's simple - just pass the name through the url: url.com/users/marine_lorphelin

This will set the :id parameter to marine_lorphelin, with which you'll be able to look up the name through your model:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def show
      @user = User._______
   end
end

If you were using a database with your user model, you'd be able to use the following:

def show
   @user = User.find_by name: params[:id]
end

Since you're not, you'll have to attach your XML hash to your model somehow. This, I don't know without specifics such as where you're getting your data from, how you're accessing it, and which routes you're going to send to invoke it.

Upvotes: 0

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34338

In your Rails app, the data that you show in your views, do not necessarily have to come from/through the database. You can always show any data you want in your views.

For example, in your index action, if you have this:

@users = [{name => "alex"}, {name => "peter"}, {name => "john"}]

Then, in your index view, you can show only those users by looping through the @users instance variable.

Same for show page as well.

If you want to show the users by name in your show page, you have to set the users by name in an instance variable e.g. @users_by_name:

@users_by_name = User.find_by(name: user_name)
# or you can hard code the values if you want like index action

and then this @users_by_name instance variable will be available in your show view so that you can loop through that and show the user names.

Originally, the show page is designed for showing a particular user related information, but you can show whatever information you want going against the conventions.

To be able to have a route like this: localhost:3000/users/alex that will show the user alex's information, you can add a route in your routes.rb file:

get 'users/:name', to: "users#show"

And, in your controller's show action, something like this:

 def show
   @user = User.find(params[:name])
 end

Then, show the @user information in your view page.

P.S. This is not a good idea to find user by name as there might be more than one user with same name in the database and it will create conflict/ or give wrong data in such situations.

Upvotes: 2

Related Questions