Is it possible to create a form for a simple class?

I just want to be able to edit the properties of a class that is not a successor to the ActiveRecord class.

Here is my class /app/model/entry.rb:

class Entry attr_accessor :title, :body end 

Here is the controller:

 class DiaryController < ApplicationController def new @entry = Entry.new end end 

Here is a view:

 <%= form_for(@entry) do |f| %> <%= f.text_field :title %> <br /> <%= f.text_area :body %> <br /> <% end %> 

I got an error while opening the form:

undefined method `` model_name '' for Entry: Class

Here is the full stack:

 Extracted source (around line #1): 1: <%= form_for(@entry) do |f| %> 2: <%= f.text_field :title %> <br /> 3: <%= f.text_area :body %> <br /> 4: <% end %> Full trace: activemodel (3.0.6) lib/active_model/naming.rb:95:in `model_name_from_record_or_class' activemodel (3.0.6) lib/active_model/naming.rb:82:in `singular' actionpack (3.0.6) lib/action_view/helpers/form_helper.rb:312:in `form_for' app/views/diary/new.html.erb:1:in `_app_views_diary_new_html_erb___902027577_26033568_187052521' actionpack (3.0.6) lib/action_view/template.rb:135:in `block in render' activesupport (3.0.6) lib/active_support/notifications.rb:54:in `instrument' actionpack (3.0.6) lib/action_view/template.rb:127:in `render' actionpack (3.0.6) lib/action_view/render/rendering.rb:59:in `block in _render_template' activesupport (3.0.6) lib/active_support/notifications.rb:52:in `block in instrument' activesupport (3.0.6) lib/active_support/notifications/instrumenter.rb:21:in `instrument' activesupport (3.0.6) lib/active_support/notifications.rb:52:in `instrument' actionpack (3.0.6) lib/action_view/render/rendering.rb:56:in `_render_template' actionpack (3.0.6) lib/action_view/render/rendering.rb:26:in `render' actionpack (3.0.6) lib/abstract_controller/rendering.rb:115:in `_render_template' actionpack (3.0.6) lib/abstract_controller/rendering.rb:109:in `render_to_body' actionpack (3.0.6) lib/action_controller/metal/renderers.rb:47:in `render_to_body' actionpack (3.0.6) lib/action_controller/metal/compatibility.rb:55:in `render_to_body' actionpack (3.0.6) lib/abstract_controller/rendering.rb:102:in `render_to_string' actionpack (3.0.6) lib/abstract_controller/rendering.rb:93:in `render' actionpack (3.0.6) lib/action_controller/metal/rendering.rb:17:in `render' actionpack (3.0.6) lib/action_controller/metal/instrumentation.rb:40:in `block (2 levels) in render' activesupport (3.0.6) lib/active_support/core_ext/benchmark.rb:5:in `block in ms' c:/Ruby192/lib/ruby/1.9.1/benchmark.rb:309:in `realtime' activesupport (3.0.6) lib/active_support/core_ext/benchmark.rb:5:in `ms' actionpack (3.0.6) lib/action_controller/metal/instrumentation.rb:40:in `block in render' actionpack (3.0.6) lib/action_controller/metal/instrumentation.rb:78:in `cleanup_view_runtime' activerecord (3.0.6) lib/active_record/railties/controller_runtime.rb:15:in `cleanup_view_runtime' actionpack (3.0.6) lib/action_controller/metal/instrumentation.rb:39:in `render' actionpack (3.0.6) lib/action_controller/metal/implicit_render.rb:10:in `default_render' actionpack (3.0.6) lib/action_controller/metal/implicit_render.rb:5:in `send_action' actionpack (3.0.6) lib/abstract_controller/base.rb:150:in `process_action' actionpack (3.0.6) lib/action_controller/metal/rendering.rb:11:in `process_action' actionpack (3.0.6) lib/abstract_controller/callbacks.rb:18:in `block in process_action' activesupport (3.0.6) lib/active_support/callbacks.rb:436:in `_run__776311234__process_action__123531476__callbacks' activesupport (3.0.6) lib/active_support/callbacks.rb:410:in `_run_process_action_callbacks' activesupport (3.0.6) lib/active_support/callbacks.rb:94:in `run_callbacks' actionpack (3.0.6) lib/abstract_controller/callbacks.rb:17:in `process_action' actionpack (3.0.6) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action' activesupport (3.0.6) lib/active_support/notifications.rb:52:in `block in instrument' activesupport (3.0.6) lib/active_support/notifications/instrumenter.rb:21:in `instrument' activesupport (3.0.6) lib/active_support/notifications.rb:52:in `instrument' actionpack (3.0.6) lib/action_controller/metal/instrumentation.rb:29:in `process_action' actionpack (3.0.6) lib/action_controller/metal/rescue.rb:17:in `process_action' actionpack (3.0.6) lib/abstract_controller/base.rb:119:in `process' actionpack (3.0.6) lib/abstract_controller/rendering.rb:41:in `process' actionpack (3.0.6) lib/action_controller/metal.rb:138:in `dispatch' actionpack (3.0.6) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch' actionpack (3.0.6) lib/action_controller/metal.rb:178:in `block in action' actionpack (3.0.6) lib/action_dispatch/routing/route_set.rb:62:in `call' actionpack (3.0.6) lib/action_dispatch/routing/route_set.rb:62:in `dispatch' actionpack (3.0.6) lib/action_dispatch/routing/route_set.rb:27:in `call' rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in `block in call' rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in `block in recognize' rack-mount (0.6.14) lib/rack/mount/code_generation.rb:68:in `optimized_each' rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in `recognize' rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in `call' actionpack (3.0.6) lib/action_dispatch/routing/route_set.rb:493:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/head.rb:14:in `call' rack (1.2.2) lib/rack/methodoverride.rb:24:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/params_parser.rb:21:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/flash.rb:182:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/cookies.rb:302:in `call' activerecord (3.0.6) lib/active_record/query_cache.rb:32:in `block in call' activerecord (3.0.6) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache' activerecord (3.0.6) lib/active_record/query_cache.rb:12:in `cache' activerecord (3.0.6) lib/active_record/query_cache.rb:31:in `call' activerecord (3.0.6) lib/active_record/connection_adapters/abstract/connection_pool.rb:354:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/callbacks.rb:46:in `block in call' activesupport (3.0.6) lib/active_support/callbacks.rb:416:in `_run_call_callbacks' actionpack (3.0.6) lib/action_dispatch/middleware/callbacks.rb:44:in `call' rack (1.2.2) lib/rack/sendfile.rb:107:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/remote_ip.rb:48:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call' railties (3.0.6) lib/rails/rack/logger.rb:13:in `call' rack (1.2.2) lib/rack/runtime.rb:17:in `call' activesupport (3.0.6) lib/active_support/cache/strategy/local_cache.rb:72:in `call' rack (1.2.2) lib/rack/lock.rb:11:in `block in call' <internal:prelude>:10:in `synchronize' rack (1.2.2) lib/rack/lock.rb:11:in `call' actionpack (3.0.6) lib/action_dispatch/middleware/static.rb:30:in `call' railties (3.0.6) lib/rails/application.rb:168:in `call' railties (3.0.6) lib/rails/application.rb:77:in `method_missing' railties (3.0.6) lib/rails/rack/log_tailer.rb:14:in `call' rack (1.2.2) lib/rack/content_length.rb:13:in `call' rack (1.2.2) lib/rack/handler/webrick.rb:52:in `service' c:/Ruby192/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service' c:/Ruby192/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run' c:/Ruby192/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread' 

Is it possible to edit class properties using form_for -tag?

+6
source share
5 answers

jdc answered this, but did not show the actual implementation that you requested. As stated in jdc, you need to enable some ActiveModel modules that will provide your ruby ​​class with the functions you need.

It looks like you need ActiveModel :: Naming and ActiveModel :: AttributeMethods.

 class Entry extend ActiveModel::Naming include ActiveModel::AttributeMethods end 

The first line will give you model_name , and the second line will allow your model to work with form helpers. There are other lines you can use: make sure the blog is sent in response to the jdc or Rails API .

Additional links with detailed information:

http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html

http://railscasts.com/episodes/219-active-model

+5
source

This blog entry should start with you:

http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/

You can enable some of the modules that ActiveRecord uses to get things like validation and serialization. Then, if you want something like a β€œsave” method that does not go to the database, just create it. I did this for the contact model. This is not AR, just a simple old Ruby object that extracts some ActiveModel elements for validation, provides some necessary methods, then the save method just starts the email. I think there is even a mix that you can use to take care of this initialization stuff, which I do to allow bulk assignment at creation, but I did not look at it very carefully. This object looks like an AR object with the front end, so all the main helpers work.

 class Contact include ActiveModel::Validations attr_accessor :id, :name, :email, :subject, :body validates :name, :presence => true validates :email, :presence => true validates :subject, :presence => true validates :body, :presence => true def initialize(attributes = {}) attributes.each do |key, value| self.send("#{key}=", value) end @attributes = attributes end def read_attribute_for_validation(key) @attributes[key] end def to_key end def save if self.valid? ContactNotifier.website_contact(self).deliver return true end false end end 
+2
source

On the one hand, your entry model file should start as follows:

 class Entry < ActiveRecord::Base 
0
source

It looks like an error you received from the following line in form_helper.rb:

 object_name = options[:as] || ActiveModel::Naming.param_key(object) 

If you specified hardcode: as => "Entry", you will get a little further. Or you can extend the class to respond to the model_name method. Here is the code in ActiveModel :: Naming that calls the model name:

  def self.model_name_from_record_or_class(record_or_class) (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name end 

I could continue to follow the challenges, but I would recommend that you follow it yourself. In the end, you will find a call that returns a hash of the attributes and values ​​that the form builder uses in form_for.

Just look at the source of the rails, see where your code is causing the error, and extend your class to answer the correct call. Keep doing this and your model will respond normally. You do not have to be an activerecord model to look, walk and sound like an activerecord model.

0
source

I found this RailsCasts Episode # 193 to be very helpful with what you are trying to do.

0
source

Source: https://habr.com/ru/post/895847/


All Articles