Question

I am using rails 4.0 I wonder how to validate date_select with activemodel

let's suppose I have the code as follow

app/models/book.rb

class Book
  include ActiveModel::Model
  include ActiveModel::Validations

  attr_accessor :title, :written_on

  validates :title, presence: true, allow_blank: false
  # How validates :written_on if I use date_select Please look in my view below
end

app/controllers/books.rb

class BooksController < ApplicationController
   #...
   def new
     @book = Book.new
   end

   def create
     @book = Book.new(book_params)
     if @book.valid?
       #Do something
     end
   end
   #...
end

app/views/books/new.html.erb

<% form_for @book do |f| %>
  ...
  <%= f.date_select :written_on %>
  ...
<% end %> 

I have also try adding

attr_accessor 'written_on(1i)'

to my book model but I got the error invalid attribute name 'written_on(1i)'

Really appreciated for the help here.

Was it helpful?

Solution

Just to clarify, I think you're asking why you're not even able to set the written_on attribute, let alone validate it-- when I used your exact code locally and tried to create a new book, on submit I got undefined method `written_on(1i)=' for Book.

This is because the Book model isn't inheriting from ActiveRecord::Base; you're just including ActiveModel::Model and ActiveModel::Validations. The Rails guide on form helpers says "when Active Record sees parameters with such names it knows they must be combined with the other parameters and given to a constructor appropriate to the column type."

So I started looking through the Rails source to see where this functionality was implemented, and it's currently in ActiveRecord::AttributeAssignment. There is currently an open pull request that moves this functionality to ActiveModel so that in cases like yours, you'd be able to use it by including ActiveModel::AttributeAssignment.

I'm not sure what you can do until that gets merged in and released. I tried including ActiveRecord::AttributeAssignment and still got the same error, and looking at the pull request, it doesn't seem to be that straightforward. You could fork Rails and apply that pull request, but you'd have to maintain your own Rails for a while until that lands, then get back on a released version.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top