Domanda

I am new to Ruby and Sinatra but I've read a bit about Rails. One of the things Rails masters tell us to do is to leave code out of the templates.

Well, here is my code, right where the information is needed in my template. It works but, for the sake of learning the best practices, how could I move this out of my template into my app.rb file without repeating it in every block of code (CRUD) which relies on the template?

<h2>Status</h2>
<ul>
  <li>Received<span><%= Inbox.count %></span></li>
  <li>Sent<span><%= Outbox.all(:processed => 1).count %></span></li>
  <li><Scheduled<span><%= Outbox.all(:error => -1).count %></span></li>
  <li>Error<span><%= Outbox.all(:error.not => [-1,0]).count %></span></li>
</ul>

Thanks for the pointers.

È stato utile?

Soluzione 2

As an alternative to @Beat Richartz's answer - not because it's wrong but because there are lots of alternatives…

1. Helpers

Helpers are available in templates. e.g.

helpers do
  def mailbox_stats
    @mailbox_stats ||= {
      :inbox_count     => Inbox.count
      :sent_count      => Outbox.all(:processed => 1).count
      :scheduled_count => Outbox.all(:error => -1).count
      :errored_count   => Outbox.all(:error.not => [-1,0])
    }
  end
end

and in the template:

<h2>Status</h2>
<ul>
  <li>Received<span><%= mailbox_stats[:inbox_count] %></span></li>
  <li>Sent<span><%= mailbox_stats[:sent_count]  %></span></li>
  <li><Scheduled<span><%= mailbox_stats[:scheduled_count] %></span></li>
  <li>Error<span><%= mailbox_stats[:errored_count] %></span></li>
</ul>

2. Settings

Settings probably aren't the best idea for this situation, but it can be done, maybe if you wanted to set some defaults:

config do
  set :mailbox_stats, {
      :inbox_count     => 0
      :sent_count      => 0
      :scheduled_count => 0
      :errored_count   => 0
    }
end

before do
  if @user.has? :inbox # or something relevant
    settings.mailbox_stats.replace( {
      :inbox_count     => Inbox.count
      :sent_count      => Outbox.all(:processed => 1).count
      :scheduled_count => Outbox.all(:error => -1).count
      :errored_count   => Outbox.all(:error.not => [-1,0])
    })
 end
end

<h2>Status</h2>
<ul>
  <li>Received<span><%= settings.mailbox_stats[:inbox_count] %></span></li>
  <li>Sent<span><%= settings.mailbox_stats[:sent_count]  %></span></li>
  <li><Scheduled<span><%= settings.mailbox_stats[:scheduled_count] %></span></li>
  <li>Error<span><%= settings.mailbox_stats[:errored_count] %></span></li>
</ul>

3. Local variables

Like limiting your scope?

get('/or_so') do
  erb :your_template, :locals => { :mailbox_stats => {
          :inbox_count     => Inbox.count
          :sent_count      => Outbox.all(:processed => 1).count
          :scheduled_count => Outbox.all(:error => -1).count
          :errored_count   => Outbox.all(:error.not => [-1,0])
    }
  }
end

in the template:

<h2>Status</h2>
<ul>
  <li>Received<span><%= mailbox_stats[:inbox_count] %></span></li>
  <li>Sent<span><%= mailbox_stats[:sent_count]  %></span></li>
  <li><Scheduled<span><%= mailbox_stats[:scheduled_count] %></span></li>
  <li>Error<span><%= mailbox_stats[:errored_count] %></span></li>
</ul>

I'd probably use a helper.

Altri suggerimenti

Just load the counts into instance variables where you define the routes:

get('/or_so') do
  @inbox_count     = Inbox.count
  @sent_count      = Outbox.all(:processed => 1).count
  @scheduled_count = Outbox.all(:error => -1).count
  @errored_count   = Outbox.all(:error.not => [-1,0])

  erb :your_template
end

If you're going to load these over multiple pages, there's also before

before(/this|insane|regexp|to|grep|locations/) do
  # assign variables
end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top