简体   繁体   中英

Automating setting instance variables in single purpose controllers that are used by different models

Say I have two models, Email and Message , with a boolean read attribute, and to mark them read I add a concern with mark_read and mark_unread patch members that route to ReadablesController .

I'd like to make it so that set_readable is automatic, not requiring me to manually query the params, and instead just work for all models with a read attribute. Is there a simple way to accomplish that?

class ReadablesController < ApplicationController
  before_action :set_readable

  ...

  def mark_read
    @readable.read = true
    @readable.save

    flash[:notice] = "#{@readable.class.to_s} marked read."
    redirect_to :back
  end

  def mark_unread
    @readable.read = false
    @readable.save

    flash[:notice] = "#{@readable.class.to_s} marked unread."
    redirect_to :back
  end

  private

  def set_readable
    throw "error" if params[:email_id].present? && params[:message_id].present?

    @readable = Email.find(params[:email_id]) if params[:email_id].present?
    @readable = Message.find(params[:message_id]) if params[:message_id].present?
  end
end

You can check if a model has read attribute with has_attribute?(:read) . From there it is trivial to call your mark_read and mark_unread methods.

@model.mark_read if @model.has_attribute?(:read)

This probably goes to your controller's set_readable method where it still will have to check a relevant param, say, params[:read] to invoke the logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM