Tableless model in rails 3.1

前端 未结 6 1668
小蘑菇
小蘑菇 2021-02-04 17:04

Looks like this method doesn\'t work anymore in rails 3.1. So, does someone have a working solution?

Actually, I\'ve found this gist. It solves problems with colum

相关标签:
6条回答
  • 2021-02-04 17:31

    For Rails 3.2 there is the activerecord-tableless gem. Its a gem to create tableless ActiveRecord models, so it has support for validations, associations, types.

    When you are using the recommended way to do it in Rails 3.x there is no support for association nor types.

    0 讨论(0)
  • 2021-02-04 17:34

    You should create your own model class and mix in the parts of ActiveModel (for example, validations) that you require. This blog post from Yehuda Katz has the details.

    0 讨论(0)
  • 2021-02-04 17:38

    and For Rails 3.2 the version of RUBY should be preferred 1.9.3 to avoid incompatibilities.

    0 讨论(0)
  • 2021-02-04 17:42

    This tableless thing seems more and more sort of a hack, but the mix just isn't the same thing (don't remember exactly what didn't work now, I've dealt with it some months ago, returned to it because upgrade to 3.1 broke it). The 3.1.0rc4 version worked with 'columns_hash' method override, the 3.1.0 requires also a 'column_defaults' override. So here's a version that passes my project tests.

    class Tableless < ActiveRecord::Base
      def self.columns
        @columns ||= [];
      end
    
      def self.column(name, sql_type = nil, default = nil, null = true)
        columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,
          sql_type.to_s, null)
      end
    
      def self.columns_hash
        @columns_hash ||= Hash[columns.map { |column| [column.name, column] }]
      end
    
      def self.column_names
        @column_names ||= columns.map { |column| column.name }
      end
    
      def self.column_defaults
        @column_defaults ||= columns.map { |column| [column.name, nil] }.inject({}) { |m, e| m[e[0]] = e[1]; m }
      end
    
      # Override the save method to prevent exceptions.
      def save(validate = true)
        validate ? valid? : true
      end
    end
    

    Hope it works for you,

    -- José

    0 讨论(0)
  • 2021-02-04 17:44

    The simplest tableless model in Rails 3.1 is:

    class Session
      include ActiveModel::Validations
      include ActiveModel::Conversion
      extend ActiveModel::Naming
    
      attr_accessor :email, :password
      validates :email, :presence => true
      validates :password, :presence => true
    
      def initialize(attributes = {})
        if attributes
          attributes.each do |name, value|
            send("#{name}=", value)
          end
        end
      end
    
      def persisted?
        false
      end
    end
    

    The ActiveModel::Validations is optional (only if validations are used). Also the constructor is not required (but highly desireable).

    0 讨论(0)
  • 2021-02-04 17:45

    For Rails / ActiveRecord 5.0 you need to redefine private def self.load_schema! to avoid checking the table_name. Also, notice a little hack for the column method (Type).

    Here's the complete listing for Tableless model for Rails 5.0 / ActiveRecord 5.0

    class Tableless < ActiveRecord::Base
    
      def self.columns
        @columns ||= []
      end
    
      def self.column(name, sql_type = nil, default = nil, null = true)
        type = "ActiveRecord::Type::#{sql_type.to_s.camelize}".constantize.new
        columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, type, null, '')
      end
    
      def self.columns_hash
        @columns_hash ||= Hash[columns.map { |column| [column.name, column] }]
      end
    
      def self.column_names
        @column_names ||= columns.map { |column| column.name }
      end
    
      def self.column_defaults
        @column_defaults ||= columns.map { |column| [column.name, nil] }.inject({}) { |m, e| m[e[0]] = e[1]; m }
      end
    
      # Override the save method to prevent exceptions.
      def save(validate = true)
        validate ? valid? : true
      end
    
      private
    
      def self.load_schema!
        columns_hash.each do |name, column|
          self.define_attribute(
            name,
            column.sql_type_metadata,
            default: column.default,
            user_provided_default: false
          )
        end
      end
    
    end
    
    0 讨论(0)
提交回复
热议问题