0

Okay, I am attempting to perform the following which I know how to do so in PHP but not in Ruby on Rails:

SELECT * FROM calls WHERE (status = 'open') OR (status = 'pending')

Simply look in the database in the calls table for open or pending status.

I'd like to do this in Rails. Currently I've got this in my controller:

class CallsController < ApplicationController
  def index
    @calls = Call.all
  end
end

And this is my view:

<table>
  <% @cals.each do |call| %>
    <tr>
      <th><%= link_to call.id, call_path(call) %></th>
      <th><%= call.cname %></th>
      <th><%= call.cbn %></th>
      <th><%= call.email %></th>
      <th><%= call.operator  %></th>
      <th><%= call.reason  %></th>
      <th><%= call.ticket %></th>
      <th><%= call.created_at %></th>
      <th><%= call.tier %></th>
      <th><%= call.status %></th>
      <th><%= link_to 'Edit', edit_call_path(call) %></th>
      <th><%= link_to 'Remove', call_path(call), method: :delete, data: { confirm: 'Are you sure?' } %></th>
    </tr>
  <% end %>
</table>
2
  • Note that you've got an typo in your view. You're using the @cals instance variable there, but in your controller it's assigned as @calls. Commented Dec 28, 2014 at 6:34
  • Sorry. The full def index is actually. 'class CallsController < ApplicationController' 'def index' '@calls = Call.all' '@cals = Call.all' end The cals I am wanting to define the open or pending since I have two query's on the same page one to list only open or pending then another table for all.<br /> Commented Dec 28, 2014 at 7:03

1 Answer 1

2

Try this:

def index
  @calls = Call.where(status: ['open', 'pending'])
end

It's considered good practice to make sure these where calls don't leak into your controller, because they're exposing a lot of the internals of Call. You can define a scope inside the Call class:

class Call < ActiveRecord::Base
  scope :open_or_pending, -> { where(status: ['open', 'pending']) }
end

And then use that inside your controller:

def index
  @calls = Call.open_or_pending
end

Note that now, the controller doesn't need to know that Call has a status field, and what its values can be.

Sign up to request clarification or add additional context in comments.

3 Comments

+ 1 Why is it preferred to have scopes rather than where clauses in the controller? Isn't it both unlikely to leak? The scope gets converted to the same SQL anyway.
Scopes provide encapsulation and reuse. Encapsulation is useful when the underlying database changes. With scopes, you'll only have to change the scopes, not the rest of the application. If there's a complex where chain, this could be moved into a single scope, and then be broken up into smaller scopes. The controller only needs to call the top level scope and not care about the complexity. Scopes also prevent you from having to repeat the where calls over and over. It's quite common for a where chain to be copy pasted to different places. If this happens, a scope is definitely required.
I love and appreciate scopes to keep my code dry. The point I didn't quite understand is the security issue, could you maybe share a link or explain further?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.