Dry Controllers in Rails 3.2

DRY Controllers in Rails 3.2

You could use respond_with for these actions.

class AnimalController < ApplicationController
respond_to :html, :json

def index
@animals = current_user.animals.valid_animals.search(params[:search], params[:page])
respond_with @animals
end
end

DRY Controllers in Rails 3.2

You could use respond_with for these actions.

class AnimalController < ApplicationController
respond_to :html, :json

def index
@animals = current_user.animals.valid_animals.search(params[:search], params[:page])
respond_with @animals
end
end

How can I DRY up Rails Controller cache_page if=proc

Firstly you can add more than one action to caches_page. This simplify the code to:

# controller_1.rb
caches_page :flu, :baz, :if => Proc.new{ |c| c.request.format && !c.request.format.json? && !is_google_bot? && flash[:notice].nil? && flash[:error].nil? }

# controller_2.rb
caches_page :foo, :bar, :if => Proc.new{ |c| c.request.format && !c.request.format.json? && !is_google_bot? && flash[:notice].nil? && flash[:error].nil? }

Secondly, all your controllers should inherit from your ApplicationController, hence you can place this method there:

class ApplicationController < ActionController::Base
#...

private

def should_cache_pages?
request.format && request.format.json? && !is_google_bot? && flash[:notice].nil? && flash[:error].nil?
end
end

Which will simplify those lines to:

# controller_1.rb
caches_page :flu, :baz, if: :should_cache_pages?

# controller_2.rb
caches_page :foo, :bar, if: :should_cache_pages?

However you can go even one step further - if you always call caches_page method with this if key, I would consider overriding this method (not tested):

class ApplicationController < ActionController::Base
#...

def self.caches_page(*args)
options = args.extract_options!
options[:if] = Array.wrap(option[:if]) << :should_cache_pages?
super *args, options
end

private

def should_cache_pages?
request.format && request.format.json? && !is_google_bot? && flash[:notice].nil? && flash[:error].nil?
end
end

Then it simplifies to:

# controller_1.rb
caches_page :flu, :baz

# controller_2.rb
caches_page :foo, :bar

rails, can you help me DRY this common 'is the current_user permitted' checking in my controllers

How about a before_filter?

I'd recommend against explicitly telling the user there's a valid object they're not allowed to edit; they don't need to know that--just tell them it's not found.

You could also explore gems like "cancan".

How to follow DRY principles in different namespaces Rails 4.2?

There are a couple ways I can think of doing it:

  1. (NOT RECOMMENDED) - Send the urls to the same controller in your routes.rb file.

  2. Shared namespace that your controllers inherit from

For example you could have:

# controllers/shared/users_controller.rb
class Shared::UsersController < ApplicationController
def index
@users = User.all
end
end

# controllers/api/users_controller.rb
class Api::UsersController < Shared::UsersController
end

# controllers/admin/users_controller.rb
class Admin::UsersController < Shared::UsersController
end

The above would allow you to share your index action across the relevant controllers. Your routes file in this case would look like this:

# config/routes.rb
namespace :api do
resources :users
end
namespace :admin do
resources :users
end

That's definitely a lot of code to share one action, but the value multiplies as the number of shared actions does, and, most importantly, your code is located in one spot.

Deleting records using forms in rails 3.2

Try passing @favourite object instead of favmat_path to link_to:

<%= link_to "Unfavourite", @favourite, method: :delete %>

How to keep code DRY in rails models

That code can be abstracted into a module.

# lib/enumable.rb
module Enumable
extend ActiveSupport::Concern

module ClassMethods
def enum(name, options)
map = Hash[options.each_with_index.map { |e, i| [e, i] }]

const_set(name.to_s.pluralize.upcase, map)

define_method name do
map.key(read_attribute(name))
end

define_method "#{name}=" do |value|
write_attribute(name, map[value])
end
end
end
end

Rails does not autoload from lib by default. Add it to the application config.

# config/application.rb
config.autoload_paths += %W(#{config.root}/lib)

Include the new module into your model.

# app/models/project.rb
class Project < ActiveRecord::Base
include Enumable
enum :status, [:approval, :rejected, :idle]
end

$ rails c
Loading development environment (Rails 3.2.9)
1.9.3-p327 :001 > project = Project.new
=> #<Project id: nil, status: nil, created_at: nil, updated_at: nil>
1.9.3-p327 :002 > project.status = :rejected
=> :rejected
1.9.3-p327 :003 > project.status
=> :rejected
1.9.3-p327 :004 > Project::STATUSES
=> {:approval=>0, :rejected=>1, :idle=>2}

Rails 3.2 how to make scoped resources

What I think you are trying to accomplish is associations. And instead of generating controllers, you should probably generate scaffolds (which includes a model, controller, and default views). At the very least, you will need group and page models.

Then add has_many :pages in your group model. And add belongs_to :group in your page model. Then you need to add a group_id column to your page model/database.

However, if I'm wrong and all you are trying to do is paginate groups, then use the will_paginate gem.

I would also suggest you go through Mike Hartl's tutorial. It will give you a great background and you will learn rails terminology and basic techniques.



Related Topics



Leave a reply



Submit