ActiveModel - View - Controller in Rails instead of ActiveRecord?

后端 未结 2 1532
傲寒
傲寒 2021-02-05 13:11

I\'m trying to use ActiveModel instead of ActiveRecord for my models because I do not want my models to have anything to do with the database.

Below is my model:

<
2条回答
  •  别跟我提以往
    2021-02-05 13:53

    I went rooting around the Rails 3.1 source to sort this out, I figured that would be easier than searching anywhere else. Earlier versions of Rails should be similar. Jump to the end if tl;dr.


    When you call form_for(@user), you end going through this:

    def form_for(record, options = {}, &proc)
      #...
      case record
      when String, Symbol
        object_name = record
        object      = nil
      else
        object      = record.is_a?(Array) ? record.last : record
        object_name = options[:as] || ActiveModel::Naming.param_key(object)
        apply_form_for_options!(record, options)
      end
    

    And since @user is neither a String nor Object, you go through the else branch and into apply_form_for_options!. Inside apply_form_for_options! we see this:

    as = options[:as]
    #...
    options[:html].reverse_merge!(
      :class  => as ? "#{as}_#{action}" : dom_class(object, action),
      :id     => as ? "#{as}_#{action}" : dom_id(object, action),
      :method => method
    )
    

    Pay attention to that chunk of code, it contains both the source of your problem and the solution. The dom_id method calls record_key_for_dom_id which looks like this:

    def record_key_for_dom_id(record)
      record = record.to_model if record.respond_to?(:to_model)
      key = record.to_key
      key ? sanitize_dom_id(key.join('_')) : key
    end
    

    And there's your call to to_key. The to_key method is defined by ActiveRecord::AttributeMethods::PrimaryKey and since you're not using ActiveRecord, you don't have a to_key method. If you have something in your model that behaves like a primary key then you could define your own to_key and leave it at that.

    But, if we go back to apply_form_for_options! we'll see another solution:

    as = options[:as]
    

    So you could supply the :as option to form_for to generate a DOM ID for your form by hand:

    <%= form_for(@user, :as => 'user_form') do |f| %>
    

    You'd have to make sure that the :as value was unique within the page though.


    Executive Summary:

    • If your model has an attribute that behaves like a primary key, then define your own to_key method that returns it.
    • Or, supply an appropriate :as option to form_for.

提交回复
热议问题