Chef - Passing Attributes in an array to a template as multiple lines - ruby

In my attributes I am trying to create server admins to be passed to a template. However, because of how the template is read by the linux server, they need to be individual lines in the template for each admin.
How would I make this a reality by just using my attributes, and a template?
In the Template .erb file -
Admins= <%= node['game_server']['game_session']['admin1'] %>
Admins= <%= node['game_server']['game_session']['admin2'] %>
My attributes file lines look like this -
default['game_server']['game_session']['admin1'] = 'admin1'
default['game_server']['game_session']['admin2'] = 'admin2'
I want to make an Array in attributes, and have the template.erb file pull them... Something like this would be nice in an attribute file instead of individual lines defining each admin -
An Example of what I'd like to do (if possible) -
default['game_server']['server_admins'] = {
'admin1': { 'Admins=': 'admin1' },
'admin2': { 'Admins=': 'admin2' },
}
I'm just learning Chef as an Ops person, so sorry for a noob question. I don't know much about programming languages yet.

attributes:
default['game_server']['server_admins'] = ['admin1', 'admin2']
template:
<% node['game_server']['server_admins'].each do |admin| %>
Admins= <%= admin %>
<% end %>

Related

Rails 5 rendering partials and passing data

I'm having trouble getting traction on what the general ways data gets passed around from and is made available to partials.
For example:
I have a controller handing off an instance variable to a template that renders a partial:
static_pages_controller.rb:
def home
#feed_items = current_user.feed
end
home.html.erb:
<%= render 'shared/feed' %>
_feed.html.erb:
<%= render #feed_items %>
Now, inside my User model is an instance method that reaching into the database to get her posts:
user.rb:
def feed
Micropost.where("user_id = ?", id)
end
So somehow because Micropost.where(...) returns a collection of microposts is that how Rails knows to go from _feed.html.erb to another partial where the <li> is defined for how microposts want to be defined?
_micropost.html.erb:
<li id="micropost-<%= micropost.id %>">
<%= link_to adorable_avatar_for(micropost.user, size: 50), micropost.user %>
</li>
And also is it just a convention that because I'm really handling a collection of microposts that Rails knows to give the micropost variable?
Your questions are answered in the Ruby on Rails Guides on Layouts and Rendering. It's worth reading the information on partials that comes before the quoted passages below as well:
Every partial also has a local variable with the same name as the
partial (minus the underscore). You can pass an object in to this
local variable via the :object option:
<%= render partial: "customer", object: #new_customer %>
Within the customer partial, the customer variable will refer to
#new_customer from the parent view. (Earlier the Guide instructs that to specify other options for render(), e.g. object:, you have to explicitly specify partial: and the name of the partial.)
If you have an instance of a model to render into a partial, you can
use a shorthand syntax:
<%= render #customer %>
Assuming that the #customer instance variable contains an instance of
the Customer model, this will use _customer.html.erb to render it and
will pass the local variable customer into the partial which will
refer to the #customer instance variable in the parent view.
3.4.5 Rendering Collections
Partials are very useful in rendering collections. When you pass a
collection to a partial via the :collection option, the partial will
be inserted once for each member in the collection:
index.html.erb:
<h1>Products</h1>
<%= render partial: "product", collection: #products %>
_product.html.erb:
<p>Product Name: <%= product.name %></p>
When a partial is called with a pluralized collection, then the
individual instances of the partial have access to the member of the
collection being rendered via a variable named after the partial. In
this case, the partial is _product, and within the _product partial,
you can refer to product to get the instance that is being rendered.
There is also a shorthand for this. Assuming #products is a collection
of product instances, you can simply write this in the index.html.erb
to produce the same result:
<h1>Products</h1>
<%= render #products %>
Rails determines the name of the partial to use by looking at the
model name in the collection. In fact, you can even create a
heterogeneous collection and render it this way, and Rails will choose
the proper partial for each member of the collection:
index.html.erb:
<h1>Contacts</h1>
<%= render [customer1, employee1, customer2, employee2] %>
customers/_customer.html.erb:
<p>Customer: <%= customer.name %></p>
employees/_employee.html.erb:
<p>Employee: <%= employee.name %></p>
In this case, Rails will use the customer or employee partials as
appropriate for each member of the collection.
In the event that the collection is empty, render will return nil, so
it should be fairly simple to provide alternative content.
<h1>Products</h1>
<%= render(#products) || "There are no products available." %>

Rails 4 - Controller Edit Action Returning Wrong Record

I have a Comment model which belongs to both User and Story. Creating a comment correctly associated to the appropriate User and Story is working fine but when trying to edit the comment my edit action appears to retrieving the wrong record.
The offending action in comments_controller.rb:
def edit
#story = Story.find_by(params[:story_id])
#comment = #story.comments.find_by(params[:id])
end
The link used to render the comments/edit view:
<%= link_to 'edit', edit_story_comment_path(comment.story_id, comment.id) %>
The corresponding view:
<%= form_for(#comment, url: { controller: 'comments', action: 'update' }) do |f| %>
<%= f.text_area :content %>
<%= f.submit "update" %>
<% end %>
The edit view appears to be rendering the most recently added comment regardless of which #comment I am trying to edit.
You're using find_by, which is basically a magic find_by_X method, with no fields specified. find_by(1) generates invalid SQL for me using Postgres, but it might be that whatever database back-end your using accepts it.
Regardless, find_by certainly won't do what you want it to do.
You should be using find, if you want to find records by id:
#story = Story.find(params[:story_id])

rails sending code block to partial

Rails 3.2.13 & ERB
I am trying to get send some link_to items to a partial. I am sending in a title to the partial successfully as below.
<%= render :partial =>'form',
:locals => {:page_title => t(:'<h2>Editing Feature</h2>')}
What I dont like is that I am currently doing this:
<%= link_to 'Show', #feature %> |
<%= link_to 'Back', features_path %>
as part of the primary page. I would like to take this codeblock and send it to the partial for rendering there. The primary reason is the simple_form is defined in the partial and I have a well that contains everything on that page. Except for the two link_to items down on the bottom of the page. If I could pass them into the partial somehow (I assume as a code block) then I can decide where to place them and how to render them in the form itself instead of kind of as an afterthought.
Thanks.
Typically we use partials to break off HTML chunks into separate modular components and reduce repetition. Partials have the same variable context as the template that rendered them, so as-is, you wouldn't have any trouble simply relocating your links to your partial and everything should just work.
I think the better practice, however, would be to pass your instance variable as a local to reduce coupling with your controller. Something like:
Your view:
<%= render :partial =>'form',
:locals => {:page_title => t(:'<h2>Editing Feature</h2>'),
:feature => #feature} %>
_form.html.erb:
<%= link_to 'Show', feature %> |
<%= link_to 'Back', features_path %>
This way, if you were to render the partial elsewhere in your application you don't need to have an instance variable handy. An example situation where this could be useful would be looping through multiple "features" (a la an index view) and spitting out the relevant HTML as defined in the partial.

ruby on rails 3.1 fragment caching

I have an app and I'd like to cache some parts of the page, and I have been reading a lot about the ways to do this.
I understand that fragment caching is the best way to do it on my project, but I canĀ“t find a simple example to learn how to implement this.
I would like to use the fragment cache with autoexpire.
<% cache(:action => 'recent', :action_suffix => 'all_products') do %>
All available products:
<% Product.all.each do |p| %>
<%= link_to p.name, product_url(p) %>
<% end %>
<% end %>
Where do I set the autoexpire? any examples around? how can I do this?
In your product model you can do something like this
after_save :expire_caches
after_destroy :expire_caches
# can't do this in a sweeper since there isn't a controller involved
def expire_caches
ActionController::Base.cache_store.delete_matched(%r{product\?for=\d+&fragment=products})

How to do a Switch based on controller with ruby on rails?

How could one do switch in ruby on rails something like:
case controller "home"
do home
case controller "about"
do about
else
do home
I currently have this code:
<% case current_page(:controller) %>
<% when "forums" %>
<%= render :partial => 'shared/sidebar/sidebar_forums' %>
<% when "events" %>
<%= render :partial => 'shared/sidebar/sidebar_events' %>
<% else %>
<%= render :partial => 'shared/sidebar/sidebar_frontpage' %>
<% end %>
Quoting from http://rails.nuvvo.com/lesson/6371-action-controller-parameters:
The params hash will always contain the :controller and :action keys, but you should
use the methods controller_name and action_name instead to access these values. Any other parameters defined by the routing, such as :id will also be available.
So you should definitely be able to access it via params[:controller], and, if the controller_name method is in scope in a view, you should use that instead.
As for the switch syntax itself, you do need to do it like
case controller_name
when "home"
do_home
when "about"
do_about
else
do_default
end
You could do some hacking and get
case true
when controller "home"
do_home
when controller "about"
do_about
else
do_default
end
But why?
Whenever you had to do something like this, that means there is something not right with the application design. Not that I have never done that in the past but I dont do this now and it is being frowned upon.
Instead of doing what you are doing now, if you namespace your controllers appropriately according to their responsibilities, after all they are just classes and handle the requests coming from the users,etc., then you may not have to do this switch statement. For example, after namespacing them you may have different layouts made of different partials for your views which may not require you to do this switching in your controller/views hence keeping the code clean.

Resources