Sinatra query collection - ruby

I'm new to Sinatra and I'm trying to figure out how querying a collection in templates work. In this particular example I'm trying to find out if in a specific collection (c in this example) of objects if there is an object with a certain value.
<% if c.votes #then filter by an id for example through all of the objects... %>
yes, it exists
<% else %>
nope, doesn't exist
<% end %>
Also, I'm used to django's filters, is there a comparable documentation online that outlines the various query functions for Sinatra?

Is it just a standard collection? You could use any?, which returns true if the provided block ever finds a match. You would then test each object for the value you are looking for in that block.
<% if c.votes.any? { |a| a.id == whatever } %>
...
<% else %>
...
<% end %>
It really depends on what "votes" is.

In rails you would use <% if c.votes.present? %> which is helpful because otherwise if c.votes is an empty array the condition would evaluate to true.
In Sinatra you don't have .present?, but you have a couple options: <% unless c.vote.empty? %> or <% if !c.votes.empty %>. I don't like the readability of either option, so I would recreate add the present? method to Array:
class Array
def present?
!empty?
end
end
Where you add this depends on how you have your Sinatra app setup. One option would ti added it directly to your main app file.

Related

Conditional HTML attribute

In ActionView I need to display an attribute based on a condition.
<%= f.text_field :regmax_remote, {
:class => 'span2',
:style => "display:#{#event.regmax_remote.present? ? "block" : "none"};"
}
%>
Is there a prettier way to go about this?
The above code is fine, If you are going to use it only once in the,
But If this will be used in many places then u may need helper
def event_display_style event
event.regmax_remote.present? ? "block" : "none"
end
if you have multiple attributes based on several conditions then u can use the helper to return the attributes in hash format and use it like this.
<%= f.text_field :regmax_remote, event_display_style(#event) %>
if u want a variable hash with default hash then u can do something like this as well
<%= f.text_field :regmax_remote, {class: "span2"}.merge(event_display_style(#event)) %>
There are some other ways to make this code look better. U may also like the draper gem. which gives an object oriented control over displaying at the same time can acce view helpers.
https://github.com/drapergem/draper
You can try like the following,
<% if (#event.regmax_remote.present?) %>
<%= f.text_field :regmax_remote, class: "span2" %>
<% end %>
Do not copy the same, just edit as per your code and use this as the example.

DataMapper fetching last record using .last throws no method error if using .any? in view

Apologies for the long wined title, in my app I am trying to retrive e the last record from the database that matches the params I have passed to it.
#goals = Weight.last(:is_goal=>true,:user_id=>#user.id)
In my views I want to run a conditional that checks if there are any present and if it has it will display a div.
<% if #goals.any? %>
<% #goals.each do |goal| %>
<p><%= goal.amount %></p>
<% end %>
<% end %>
But for some reason this throws a no method error NoMethodError at /
undefined method 'any?'. If I change the .last to .all it works
#goals = Weight.all(:is_goal=>true,:user_id=>#user.id)
Is there any reason behind this or have I found a bug?
Well, .last method returns an object, .all method returns an array of objects.
And .any? is an array method. You can't call .any? on an object, it will tell you that there is no method unless you have created one.

How to correct in the Sinatra show block

Sorry, I will not use the specific expression in English.
index.erb
<h1>Hello World.</h1>
<ul>
<li>item1</li>
<li>item2</li>
</ul>
<% capture_content :key do %>
I'm Here.
<% end %>
helpers
def capture_content(key, &block)
#content_hash = {}
#content_hash[key] = block.call # this block contains erb all
end
I just want capture_content in content
I hope expression is correct T_T
If you are looking to write yourself the Sinatra equivalent of the Reails content_for helper then you don't need to.
Because there is an extension called Sinatra::ContentFor which is part of the Sinatra::Contrib project which does what you want.
From the documentation:
Sinatra::ContentFor is a set of helpers that allows you to capture
blocks inside views to be rendered later during the request. The most
common use is to populate different parts of your layout from your
view.

how to check for non-nil value of associated attribute - is there a more succinct way?

I have items and they have prices in a has_one relationship. In the price object, there is a price value (unfortunately true). I'd like to be able to test for non-nil values of item.price.price. In the view, there is an add_to_order helper method that should show only if there is a price.price. I test using for this condition with:
<% if item.price && !item.price.price.nil? %>
<%=add_to_order item %>
<% end %>
but it seems pretty ugly. Is there a more succinct / 'better' way of testing for this?
thx in advance
I would try to avoid logic in your views and simply have your add_to_order method handle the item validation.
def add_to_order(item)
return unless price = item.price.try(:price)
# ... your implementation
# the items price is in the price variable for you
end
Object#try
Your view would just become:
<%=add_to_order item %>
since all your logic would be in the add_to_order helper method.
Rails provides a syntax sugar for this with the try method:
<% unless item.price.try(price).nil? %>
<%= add_to_order item %>
<% end %>
You can use try. It will work safely even if item.price is nil
<% unless item.price.try(:price) %>
<%=add_to_order item %>
<% end %>

How do I perform inline calculations on two variables within an .erb file?

I have the following .erb view in a Sinatra app:
<% sessions.each do |session| %>
<%= session.balance_beginning %>
<%= session.balance_ending %>
<% end %>
It works as expected, displaying the beginning and ending balances recorded for each session. I would like to calculate the net balances from within the .erb file, but I can't figure out how to do it. I have tried variations of this:
<% sessions.each do |session| %>
<%= session.balance_ending - session.balance_beginning %>
<% end %>
That doesn't work. I receive the following error in Sinatra:
undefined method `-' for nil:NilClass
How do I do what I'm trying to do?
Right #Zabba, in this case I think you would add a method to your Session model so you could call session.net_balance.
Then in your balance_ending and balance_beginning methods you would want to handle nil, either raise an error or return zero if that is valid.

Resources