Do I need an Enumerator for this? - ruby

I want to do this:
<div class="menu">
<%- render_menu do |title,path,children| %>
<%= link_to title, path %>
<div class="submenu">
<%= render_menu(children) do |title,path,children| %>
<%= link_to title, path %>
<%= children %>
<%- end %>
</div>
<% end %>
</div>
The method render_menu would look something like this:
def render_menu(children=nil)
children = Paths.roots if children.nil?
children.collect do |child|
[ child.title, child.path, child.children ]
end
end
I'm not sure what the render_menu needs to return to get the three params..
The render_menu will grab the default menu items if no argument is given..

You have to use yield and replace each for collect inside render_menu:
def render_menu(children=nil)
children = Paths.roots if children.nil?
children.each do |child|
yield([child.title, child.path, child.children])
end
end
You should also modify your template to not display the value returned by render_menu:
<div class="submenu">
<% render_menu(children) do |title,path,children| %>
<%= link_to title, path %>
<%= children %>
<% end %>
</div>

Related

How to output variable in sinatra without <%=

In Rails, there exist such helper as "concat" to output variables inside <% %> block for erb remplates. Which helper can I use in Sinatra to perform the same action, without using <%= %> block ? I mean, something like
<%
#code
concat "This should be rendered in HTML, not in console"
#code
%>
EDIT
The code in the view is something like this (yep, too much logic, but this is my first app in Ruby):
<% Dir.glob('uploaded/*').select do |entry| %>
<div class="singleFileItem">
<% if File.directory? entry %>
<img src="images/folder.png">
<% else
case entry.to_s.split(".")[1]
when "doc","docx" %>
<img class="pictogram" src='images/word.png'>
<% when "xls","xlsx" %>
<img class="pictogram" src='images/excel.png'>
<% when "pdf" %>
<img class="pictogram" src='images/pdf.png'>
<% when "png", "jpg", "jpeg" %>
<img class="pictogram" class="imageRaw" src="<%= entry.to_s %>">
<% else %>
<% end
end %>
<br>
<span class="subFileText">
<%= entry.to_s.split("/")[1][0..14] %>...
</span>
</div>
<% end %>
Thanks, guys, I have finally found it.
I have extended the app.rb file with
set :erb, :outvar => '#output_buffer'
def concat(text)
#output_buffer << text
end
And it works. Just type in the .erb view
<% concat "Text that should be added to render" %>
And you all done. Hope, this will help to someone with similar question

Add a class to the first child in a loop using Middleman

I am creating a slider for my blog and I want to add a collection of featured items to it, The slider requires that the first child load with the class selected.
How can I do something like if first child do this else do that
Here is what I have so far:
<ul class="cd-hero-slider">
<% blog.articles.select {|a| a.data[:featured] }.each do |article| %>
<li class="selected" style="background-image: url('https://images.unsplash.com/photo-1447014421976-7fec21d26d86?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&s=c82e04e1201234889daab5427f481731')">
<div class="cd-full-width">
<h2><%= link_to article.title, article %></h2>
<p><%= article.summary(250) %></p>
<%= link_to 'Read More', article, :class => 'cd-btn' %>
</div>
</li>
<% end %>
</ul>
Use each_with_index instead of each - this will give you the object but also the position into the array, first being 0:
<% blog.articles.select {|a| a.data[:featured] }.each_with_index do |article, index| %>
<% if index == 0 %>
<li>I'm the first!</li>
<% else %>
<li>Not the first</li>
<% end %>
<% end %>

Using carmen gem with rails

What I am trying to do is show the 2 letter abbreviation code of the countries, i.e 'US'.
After the country is selected I need to show its state or province.
but I am having a problem.
My code looks like
<%= f.select :country_code, region_options_for_select(only_us_and_france) %>
and define this in helper:
def only_us_and_france
Carmen::Country.all.select{|c| %w{US FR}.include?(c.code)}
end
I am using Rails 4.1.0.
I have solved this by :
Step1: Generated migration
rails g migration addStateCodeFieldToAccounts state_code:string
Step2: Define a method inside controller
def subregion_options
render partial: 'subregion_select'
end
Step3: Declare in routes
resources :accounts do
collection do
get 'subregion_options'
end
end
Step4: In view
<div class="input-control select state_input" data-role="input-control">
<%= f.select :country, region_options_for_select(only_us_and_france) %>
</div>
<div class="input-control select state_input" data-role="input-control">
<%= render partial: 'subregion_select', locals: {parent_region: f.object.country} %>
</div>
Step5: Make partial subregion_select
<div id="account_state_code_wrapper">
<% parent_region ||= params[:parent_region] %>
<% country = Carmen::Country.coded(parent_region) %>
<% if country.nil? %>
<em>Please select a country above</em>
<% elsif country.subregions? %>
<%= subregion_select(:order, :state_code, parent_region) %>
<% else %>
<%= text_field(:order, :state_code) %>
<% end %>
</div>
Step6: In my js file written this
$('select#account_detail_country').change(function(){
selectWrapper = $('#account_state_code_wrapper')
countryCode = $(this).val()
url = "/account_details/subregion_options?parent_region="+countryCode
console.log(url)
selectWrapper.load(url)
});
yeah and it works :) Hope this will help you.

Ruby variable each loop substitution

I need to replace X_VARIABLE in 2 places.
For the first X_VARIABLE I want to keep the text 'remove'
For the second X_VARIABLE I want to keep 'd_cars_path'
<% #cars.each do |x| %>
<% #a = #b.send(x) %>
<% if #a == true %>
<%= button_to "removeX_VARIABLE", X_VARIABLEd_cars_path(:id => #user.id), class: "btn btn-large btn-primary" %>
<% end %>
<% end %>
I am looking for some help with the variable substitution syntax. Thanks.
I'd write:
<% #cars.each do |x| %>
<% if #b.send(x) %>
<%= button_to "remove#{x}",
send(:"#{x}d_cars_path", id: #user.id),
class: "btn btn-large btn-primary" %>
<% end %>
<% end %>

Getting undefined method `klass' for nil:nilclass - Railscast #197

Hi all I followed Ryan Bates' railscasts on nested models and form, but I am getting getting undefined method `klass' for nil:nilclass. I am pretty sure it is due to the the link_to_add_fields since everything was working prior. Below is my error and other relevant code and I'm using Rails 3.1. I did a lot of googling and did not find any to solve my problem, so if you guys could help me out I would really appreciated it. Thanks for your help.
_form.html.erb
<%= form_for(#organization) do |f| %>
<% if #organization.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#organization.errors.count, "error") %> prohibited this organization from being saved:</h2>
<ul>
<% #organization.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div id="restaurant_field" class="field">
<%= f.fields_for :restaurants do |builder| %>
<%= render 'organizations/partials/restaurant_fields', :f => builder %>
<% end %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
_restaurant_fields.html.erb
<p class="fields">
<%= f.label :name, "Restaurant Name" %><br />
<%= f.text_field :name %>
<%= link_to_remove_fields "Remove", f %>
application_helper.rb
module ApplicationHelper
def link_to_remove_fields(name, f)
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, h("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"))
end
end
application.js
function remove_fields(link) {
$(link).prev("input[type=hidden]").val("1");
$(link).closest(".fields").hide();
}
function add_fields(link, association, content) {
var new_id = new Date().getTime();
var regexp = new RegExp("new_" + association, "g");
$(link).parent().before(content.replace(regexp, new_id));
}
I found that the link_to_add_fields helper won't work if the associated model is describe by a has_one. The has_one means the association does not get the klass object.
You can determine this is your problem by changing your relationship to has_many :object + s (your object name with an s) and passing your object in plural to link_to_add_fields.
You have done the same thing as this person here
Edit: (error on my part)
I am assuming you have an link_to_add_fields below this line
<%= link_to_remove_fields "Remove", f %>
as it seems that the _restaurant_fields.html.erb partial is incomplete. (no closing tag)
</p>
Remove the link_to_add_fields outside of the f.fields_for
That should solve the klass error.

Resources