If I want a custom slug

I walk through this cutstom slug.

  1. create migration add_slug to add a column inside the Post
  2. generate_slug using before_save. Read all the ActiveRecord Callbacks
  3. If you want to find a specific Post, you can not use Post.find, you have to use Post.find_by slug: 'my-post'
Read more...
What is ORM in Rails mean?

Object Relational Mapping(ORM)

This is confused topic. I had a friend ask me about the model in Rails, and I spent lots of time trying to explain to him. I suggest those who want to understand this that you need to understand how SQL works.

I quote from rails guide:

Object Relational Mapping, commonly referred to as its abbreviation ORM, is a technique that connects the rich objects of an application to tables in a relational database management system. Using ORM, the properties and relationships of the objects in an application can be easily stored and retrieved from a database without writing SQL statements directly and with less overall database access code.

Read more...
Rails concern and service object to refactor

Rails concern

This is part of the code in Launch School 301 course. And in the code below, it shows how to extract the duplicate code in different module to ActiveSupport::Concern. But there are more than one way to refactor the code. DHH in the signal v. Noise wrote an article to introduce the concerns :

Different models in your Rails application will often share a set of cross-cutting concerns. In Basecamp, we have almost forty such concerns with names like Trashable, Searchable, Visible, Movable, Taggable.

Ryan Bates of Railscasts wrote an article to talk to people not to use concern. He encourage people to use Service Object.

Read more...

why skinny controller, fat model?

If you try to read on the project Redmine project, for example, the activities_controller#index`,

This is the part if the index action:

   def index
      @days = Setting.activity_days_default.to_i

      if params[:from]
        begin; @date_to = params[:from].to_date + 1; rescue; end
      end

      @date_to ||= User.current.today + 1
      @date_from = @date_to - @days
      @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
      if params[:user_id].present?
        @author = User.active.find(params[:user_id])
      end

      @activity = Redmine::Activity::Fetcher.new(User.current, :project => @project,
                                                               :with_subprojects => @with_subprojects,
                                                               :author => @author)
      pref = User.current.pref
      @activity.scope_select {|t| !params["show_#{t}"].nil?}
      if @activity.scope.present?
        if params[:submit].present?
          pref.activity_scope = @activity.scope
          pref.save
        end
      else
      end
  #....
  end
Read more...

What transaction do?

Before beginning , let’s read some code

  # in /controllers/queue_items_controller.rb
  def update_queue
    begin
      update_queue_items
      normalize_queue_items_positions
    rescue ActiveRecord::RecordInvalid
      flash[:error] = "Invalid position numbers"
    end
    redirect_to my_queue_path
  end

  private

  def update_queue_items
    ActiveRecord::Base.transaction do
      params[:queue_items].each do |queue_item_data|
        queue_item = QueueItem.find(queue_item_data["id"])
        queue_item.update_attributes!(position: queue_item_data["position"]) if queue_item.user == current_user
      end
    end
  end
Read more...