mardi 4 août 2015

Ruby2.0: What is the difference between Ruby Refinements and Monkeypatches?

I could do some simple task in either way,

Refinements

module StringRefinements
  refine String do
    def do_something
      "bla bla bla..."
    end
  end
end

So, I can use do_something method wherever StringRefinements module was using.

Monkeypatch

class String
  def do_something
    "bla bla bla..."
  end
end

I would like to know the difference between Ruby's new concept Refinements and the one Monkeypatch. And what are the advantages of using Refinements over Monkeypatch?



via Chebli Mohamed

What is a good way to suppress 304 responses in Rack?

Rack seems to use the If-Modified-Since header. So one way to suppress 304 responses is to delete this header.

Is this a good way to suppress 304 responses? Is there a better way?



via Chebli Mohamed

Rails controllers architecture with many to many relationships

I am developing a portal via RubyOnRails where pupils, teachers and parents can participate in different contests with their art works.

There are 3 entities: Contests, Categories (competitor categories / age groups) and Nominations (kinds of activity). Contest can have many Categories. Each ContestCategory can have many Nominations. Each Category can belong to several Contests. Every Nomination can belong to many ContestCategories. So I presume there is many-to-many relationship between Contests and Categories and many-to-many relationship between ContestCategories and Nominations. I've created following models: Contest (contest.rb), Category (category.rb), Nomination (nomination.rb), ContestCategory (contest_category.rb) and ContestCategoryNomination (contest_category_nomination.rb).

My models:

class Category < ActiveRecord::Base
  has_many :contest_categories
  has_many :contests, through: :contest_categories
end

class Contest < ActiveRecord::Base
  has_many :contest_categories
  has_many :categories, through: :contest_categories
  has_many :nominations, through: :contest_categories
  has_one :provision
end

class ContestCategory < ActiveRecord::Base
  belongs_to :contest
  belongs_to :category
  has_many :contest_category_nominations
  has_many :nominations, through: :contest_category_nominations
end

class ContestCategoryNomination < ActiveRecord::Base
  belongs_to :contest_category
  belongs_to :nomination
end

class Nomination < ActiveRecord::Base
  has_many :contest_category_nominations
  has_many :contest_categories, through: :contest_category_nominations
  has_many :contests, through: :contest_categories
end

I want to create an ajax-based modal window during creation of new Contest to link it with Category and select multiple Nominations that belong to this Category.

  1. What controllers should I create to satisfy has_many relationships between my models?
  2. What are the naming conventions (singular and plural) in rails to satisfy my relationships? For example, ContestsCategoriesController or ContestCategoryNominationsController or may be ContestCategoryNominationsController?
  3. What action method should I create in this controllers to invoke to render this modal window? Should it be new_category action in CategoriesController or new action in ContestsCategoriesController or new action in ContestsCategoriesNominationsController?


via Chebli Mohamed

Ruby on Rails: if current page? is homepage, don't show form

I want to not show a form, but only if current page is NOT the home page

This is what I have so far...

I have my route setup:

root 'projects#index'

My view:

<% if !current_page?(url_for(:controller => 'projects', :action => 'index')) %>
  show some stuff
<% end %>

This doesn't show if the url is localhost:3000/projects

But it shows if its localhost:3000

So I need to somehow make sure that if its the homepage, it won't show. Also, I have search parameters for the home page, and I still don't want to show if its like localhost:3000/projects?search=blahblahblah



via Chebli Mohamed

Trying to reference earlier 'case' in a case statement

When someone tries to update a value that is not currently stored in my hash, I would like to immediately reference back to "when 'add'" without restarting the entire case statement (since I already know they want to add and don't want to prompt them again). Is there a way to reference back to the case choice -> when "add" section of my code without restarting the entire case statement? I know I could use nested case statements but I would rather not copy/paste identical code if I don't have to.

Also, sorry for the abrupt ending of the code. I just didn't want to put in anything unnecessary to the solution.

    hash = {}
    puts "Would you like to add or update this hash?"
    choice = gets.chomp
    case choice
    when "add"
      puts "What key you like to add?"
      key = gets.chomp
      puts "With what value?"
      value = gets.chomp
      hash[key] = value
    when "update"
      puts "Which key would you like to update?"
      key = gets.chomp
      if hash[key].nil?
        puts "Key not present, would you like to add it?"
        #here I would like the code that references back to "when 'add'" if the user types 'yes'    



via Chebli Mohamed

Nested forms using the Cocoon gem in Ruby on Rails 4.2

I'm building a web app using Rails 4.2 and I have a model called Strategy which has a has_many relationship to a Tactic model.

To create a view for Strategy, I need to have many nested Tactics on the form. I've been using the Cocoon gem to develop this view.

So far, I've been able to get the form to work properly for the most part but the issue is that I wanted to add a Type attribute to my Tactic model.

For a given strategy, I want to have 3 tactics of one given type, and 2 models of another.

The issue is that rendering my view, all five models are listed sequentially without any room for putting in my own HTML code around them.

Is there a simple way to separate out which of these are rendered? Right now, my view looks as follows...

<%= form_for @strategy do |f| %>
    <div class="strategy">
        <%= f.label :name %>
        <%= f.text_field :name %>
    </div>

    <div class="tactics">
        <%= f.fields_for :tactics do |i| %>
            <%= render 'tactics_fields', f: i %>
        <% end %>
    </div>

    <div class="buttons">
        <%= f.button "Save Strategy", class: 'button' %>
    </div>
<% end %>

If anyone can offer any advice, it would be greatly appreciated.



via Chebli Mohamed

extend array by n numbers while repeating elements

If I have an array like this

[1,2,3]*2 
#=> [1,2,3,1,2,3,1,2,3]

But I want to do it to certain length, that length is 1.5 the original array, preferably in one line

[1,2,3].size = 3
[1,2,3,1,2] or something like this



via Chebli Mohamed