Rails: How can I let my users choose a design? - ruby-on-rails

I am working with rails and am trying to implement a feature into my blogging application. I would like to have the option to choose a design for my blog. I would of course make the design and code them but after they are coded I would like to have the choice of using one of my designs.
How would/should I approach this?

Make controller for choosing design form list (of course check vaild of choise). Save choose in session and try this:
In layout:
= stylesheet_link_tag #custom_css
In application.rb
class ApplicationController < ActionController::Base
before_filter :check_css
def check_css
#custom_css = session[:css]
#custom_css ||= 'default'
end
end
I think that should work.
Other idea is change to different layout.
class ApplicationController < ActionController::Base
layout :custom_layout
def custom_layout
session[:css].nil? ? session[:css] : 'default'
end
end

Related

Share the same piece of data in multiple controllers and views

Lets say that we have a rails app which has a sidebar on every page that shows some data, like post archives, post categories etc. Which is the best way to share the same data on each of our controllers?
Iguess the most easy fix is to use the same before_actions on each controller, but this doesn't DRY up much our code, or maybe move all these into a parent class/cotrnoller that all controllers will inhert from, but is there a better way of doing this?
Simple Solution:
Normally, I just put these into application_controller.rb as a before_action.
Example
# app/controllers/application_controller.rb
before_action :set_sidebar_resources
# ...
private
def set_sidebar_resources
#sidebar_archives = Archive.all
#sidebar_categories = Category.all
end
Modular Solution:
Simple solution above works great until you define more and more methods and other global controller logic into ApplicationController, and then the file becomes too big to manage. The following is a less conventional approach favouring more of manageability rather than simplicity.
Example
# app/controllers/application_controller.rb
include WithSidebar
# app/controllers/concerns/with_sidebar.rb
module WithSidebar
extend ActiveModel::Concern
included do
before_action :set_sidebar_resources
private
def set_sidebar_resources
#sidebar_archives = Archive.all
#sidebar_categories = Category.all
end
end
end
Rails controllers inherit from application controller.
ex.
class ClientsController < ApplicationController
You could add before_actoion to ApplicationController that pulls the data you want into #variable and then use that variable in other controllers.
Just don't over-do it and keep your controllers skinny :)

The best way to “split” up a large Rails controller

I currently have an already-large controller that’s getting bigger. I was wondering what would be the best way to slim down my controllers. I’m not necessarily looking for the easiest way, but a safe and efficient way. I’ve been developing with Rails for a while now but I’m still not familiar with how “subclassing” works and I’m not even sure if it’s supposed to be used in this way. I was thinking maybe something like this?
class SomeController < ApplicationController
end
class MoreFunctionsController < SomeController
end
That’s currently untested – I’m still working on it right now – but I hope that this would sort of give you an idea of what direction I’m trying to go. I’m also not sure how the routing for this would look. What would be the best way to “split” up a large controller?
ActiveSupport::Concern (documentation) is what you are looking for.
Update
Something like this:
# config/application.rb
config.autoload_paths += %W(#{Rails.root}/app/controllers/concerns) # in Rails4 this is automatic
# app/controllers/my_controller.rb
class MyController < ApplicationController
include GeneralStuffConcern
def index
render text: foo
end
end
# app/controllers/concerns/general_stuff_concern.rb
module GeneralStuffConcern
extend ActiveSupport::Concern
def show
redirect_to root_path
end
protected
def foo
'fooo'
end
end
update 2
I actually recommend this more http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
update 3 (2022)
Bounded contexts https://blog.eq8.eu/article/rails-bounded-contexts.html

Rails: How to POST internally to another controller action?

This is going to sound strange, but hear me out...I need to be able to make the equivalent of a POST request to one of my other controllers. The SimpleController is basically a simplified version of a more verbose controller. How can I do this appropriately?
class VerboseController < ApplicationController
def create
# lots of required params
end
end
class SimpleController < ApplicationController
def create
# prepare the params required for VerboseController.create
# now call the VerboseController.create with the new params
end
end
Maybe I am over-thinking this, but I don't know how to do this.
Inter-controller communication in a Rails app (or any web app following the same model-adapter-view pattern for that matter) is something you should actively avoid. When you are tempted to do so consider it a sign that you are fighting the patterns and framework your app is built on and that you are relying on logic has been implemented at the wrong layer of your application.
As #ismaelga suggested in a comment; both controllers should invoke some common component to handle this shared behavior and keep your controllers "skinny". In Rails that's often a method on a model object, especially for the sort of creation behavior you seem to be worried about in this case.
You shouldn't be doing this. Are you creating a model? Then having two class methods on the model would be much better. It also separates the code much better. Then you can use the methods not only in controllers but also background jobs (etc.) in the future.
For example if you're creating a Person:
class VerboseController < ApplicationController
def create
Person.verbose_create(params)
end
end
class SimpleController < ApplicationController
def create
Person.simple_create(params)
end
end
Then in the Person-model you could go like this:
class Person
def self.verbose_create(options)
# ... do the creating stuff here
end
def self.simple_create(options)
# Prepare the options as you were trying to do in the controller...
prepared_options = options.merge(some: "option")
# ... and pass them to the verbose_create method
verbose_create(prepared_options)
end
end
I hope this can help a little. :-)

Rails: Why the default application layout is not used?

I added #sort_by attribute to my controller, and initialized it's value like this:
class ProductsController < ApplicationController
def initialize
#sort_by = :shop_brand
end
...
end
This caused the default application layout not to be used.
Why ?
What is the right way to add an attribute to a controller and initialize it ?
Overriding the constructor is probably a bad idea (as you have found). You should use a before_filter:
class ProductsController < ApplicationController
before_filter :set_defaults
...
private
def set_defaults
#sort_by = :shop_brand
end
end
However, it sounds like you want to keep state. The easiest is to store in the user's session which will automatically persist per user until they close the browser:
def set_defaults
session[:sort_by] ||= :shop_brand
end
The other option would be to pass the current sort_by value in the URL. This is harder to implement though as you'll need to ensure each link or form copies the value over to the next request. The advantage of this however is the user could have multiple tabs open with different orderings and any bookmarked link would restore the same ordering next time. This is the approach that things like search engines would use.

Is there some sort of Master Page functionality in Ruby on Rails?

I've been a .Net developer for the past seven years or so, and been working with ASP.Net for the last couple of years. I'm now using Ruby on Rails for some projects, and I'm wanting to know if there is something in Ruby on Rails that lets you do master page type stuff?
Basically, I want a way to provide a consistent look and feel for the site with a header and footer and so on, and then just have each page put its content inside of that. How do you accomplish this?
in your rails project in app/layouts/application.(html.erb|html.haml), this is the layout or equivalent for master.
You can also create other layouts and specify the layout to use for each action :
render :index, :layout => "awesome"
Or specify the layout for a whole controller :
class PostController < ActionController::Base
layout "super_awesome"
end
You can use layout which is look like master page in ASP.Net, there are many way to assign master page to your rail application :
For single page :
class EmployeesController < ApplicationController
layout "submaster"
# ---
end
submaster is located at app/views/layouts/submaster.html.erb
For whole application :
class ApplicationController < ActionController::Base
layout "main"
#...
end
main is located at app/views/layouts/main.html.erb
Layout at run-time :
class EmployeesController < ApplicationController
layout :emp_layout
def show
# ---
end
private
def emp_layout
#current_user.admin? ? "admin" : "submaster"
end
end
If current user is a admin user, they'll get a admin layout else submaster layout.
If possible, please check yield identifies in rails.

Resources