<%= f.text_field :quantity_available, :readonly => "readonly",:class=>"mg-text-field" %>
error:
undefined method `quantity_available' for #<:0xaf32b824>
In the new form I have shown "quantity_available" whose value I am getting through jquery and this field is only for displaying purpose so this has not been saved in model but I want to do same in edit form in which I am getting error as
how to resolve this?
You can define the field in the Model without it needing to be a persisted column in the table.
class Model < ActiveRecord::Base
attr_accessor :quantity_available
# other stuff here
end
For that purpose you can use text_field_tag. For more check on http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html
<%= text_field_tag 'quantity_available',nil, class: "mg-text-field", readonly: true %>
Related
I like to know how to merge two table attributes and summarize them in a single drop down.
I tried to create a method in the create form helper which i referenced the attributes of the table.
_form.html.erb
<div class="field">
<%= form.label :Destinations %>
<%= form.collection_select(:destination_id, Destination.all, :id, destname_with_klm(#createform.destination), {}, { :multiple => false } ) %>
</div>
createforms_helper.rb
module CreateformsHelper
def destname_with_klm(f)
"#{f.Destination_name}.#{f.Destination_kilometre}"
end
end
NoMethodError in Createforms#new
Showing **/app/views/createforms/_form.html.erb where line #34 raised:
undefined method `Destination_name' for nil:NilClass
the error you are getting undefined method "Destination_name" for nil:NilClass is because the parameter (f) you pass is nil
However, I think you can update the model and make the code bit cleaner. (I had a look at the formatted suggested edit and gather this info)
#app/models/destination.rb
class Destination < ActiveRecord::Base
#other code
def destination_name_with_kms
# I believe the attribute names should be lowercase
"#{Destination_name}.#{Destination_kilometre}"
end
end
#in your view
<%= form.collection_select(:destination_id, Destination.all, :id, destination_name_with_kms, {}, { :multiple => false } ) %>
If you want to go one step further, I would recommend to use a decorator gem like
Draper, and move all the UI formatting to a decorator.
I am using simple_form_for
<%= simple_form_for( #form_object, url: wizard_path, :method => :put) do |f| %>
<%= f.input :website %>
<%= f.submit %>
</div>
<% end %>
However, I am also using a Form Object
class Base
include ActiveModel::Model
# Validations
# Delegations
# Initializer
end
My issue is that my inputs are not mapping to my database columns, so https://github.com/plataformatec/simple_form#available-input-types-and-defaults-for-each-column-type
None of these show up ,and can I create custom mappings.
How can I allow Simple_form to see my column types and work correctly?
If I check the class of my delegated fields, they seem to show as :string or :integer, etc.
simple_form uses 2 methods to determine the input type field mapping from a standard model (type_for_attribute and has_attribute?). Source
Since you are wrapping the model in another layer but still want the inference that simple_form provides you just need to delegate these calls to the original model via
class Wrapper
include ActiveModel::Model
attr_reader :model
delegate :type_for_attribute, :has_attribute?, to: :model
def initialize(model)
#model = model
end
end
However if you were not wrapping the model you would need to define these methods yourself such as (using the new rails 5.2 Attribute API)
class NonWrapper
include ActiveModel::Model
include ActiveModel::Attributes
attribute :name, :string
def type_for_attribute(name)
self.class.attribute_types[name]
end
def has_attribute?(name)
attributes.key?(name.to_s)
end
end
Example
a = NonWrapper.new(name: 'engineersmnky')
a.has_attribute?(:name)
#=> true
a.type_for_attribute(:name)
#=> => #<ActiveModel::Type::Value:0x00007fffcdeda790 #precision=nil, #scale=nil, #limit=nil>
Note other additions may be required for a form object like this to work with simple_form. This answer simply explains how to handle the input mapping inference
First question: how to validate a model relation and mark it in form when validation failed.
I have a subject model:
class Subject < ActiveRecord::Base
belongs_to :semester
validates_presence_of :semester
end
In my view (form):
<%= select_tag :semester, options_from_collection_for_select(#semesters,"id","name") %>
The validates_presence_of works fine. But when the validation fails (user forgot to enter semester ). The semester input is not marked in red.
Second question: how to validate an input field.
In my view, I also have a university input field, but model subject has no relationship with university, no field university in subject table. So how to validate it and mark it in red.
Thanks in advance.
If you want to get the fields with error displayed in red "out of the box", you must use a form builder. The code will looks like f.select ... instead of using select_tag.
With the form builder, the fields with errors are created inside a <div class="field_with_errors">...</div>. The css file generated by scaffolding displays these fields in red; if you're not using it, you must add the css rules to your css.
# app/models/subject.rb
class Subject < ActiveRecord::Base
belongs_to :semester
validates :semester, :university, presence: true # new syntax http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates
end
# app/views/subjects/_form.html.erb
<%= form_for #subject do |f| %>
Semestr: <%= f.collection_select :semester_id, Semestr.all, :id, :name, prompt: true %>
University: <%= f.text_field :univercity %>
<% end %>
For more information about building forms in rails (with validations enabled) you could find there http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html
Those "red errors" that you hope for are probably coming from a form helper gem like formtastic, feel free to check that out.
I have literally no idea what your second question is asking, but if you're looking for a custom validation. Check out the rails docs on them for help.
If you'd like more help, (please) edit your question to be more clear (thanks)
I have a Rails model (persisted with Mongoid) that can be collaboratively edited by any registered user. However, I want to allow editing any particular attribute only if it was previously blank or nil.
For example, say someone created an object, and set its title attribute to "Test Product". Then another user comes along and wants to add a value for price, which until now has been nil.
What's the best way to do this, while locking an attribute that has previously been entered?
Look into the ActiveRecord::Dirty module for some nice utility methods you can use to do something like this:
NON_UPDATABLE_ATTRIBUTES = [:name, :title, :price]
before_validation :check_for_previously_set_attributes
private
def check_for_previously_set_attributes
NON_UPDATABLE_ATTRIBUTES.each do |att|
att = att.to_s
# changes[att] will be an array of [prev_value, new_value] if the attribute has been changed
errors.add(att, "cannot be updated because it has previously been set") if changes[att] && changes[att].first.present?
end
end
The easiest way, i think, is by checking for it in the form itself.
Just say add :disabled => true to the input field if the person cannot edit it.
<% if #my_object.name %>
<%= f.text_field :name, :disabled => true %>
<% else %>
<%= f.text_field :name, :disabled => true %>
<% end %>
(i think there is a prettier way to write this code)
But by using this the user has a visual feed back that he can't do something, it is always better to not allor something than to give an error message
I'm trying to fill out an array with values from checkboxes. It works just fine when creating a record, but fails validation when editing. The params look right, which is what really confuses me:
"record"=>{... "type_array"=>["accounting"], ...}
It looks the same as the params from creating a new record. The fields in New.html.erb and Edit.html.erb also use the same markup.
Edit.html.erb
<div class="field">
<%= f.label :type_array, "What type of record?" %><br />
<% ["accounting", "agriculture", "automotive"].each do |type| %>
<%= check_box_tag 'record[type_array][]', type, (true if #record.type_list.include? type),
:id => type %>
<%= label_tag type, type.titleize, :class => type %><br />
<% end %>
</div>
Parts of Record.rb
validates :type_array, :presence => true
attr_accessor :type_array
attr_accessible :type_array
before_validation :set_type_list
private
def set_type_list
self.type_list = type_array.join ',' if type_array.present?
end
Am I missing something? When I remove the type_array validation and fill out the form, it acts like type_array is empty. Somewhere along the line, it must be lost or something.
I appreciate any help.
(Sidenote: if anyone has a better way to do the list of checkboxes, let me know)
Delete the line attr_accessor :type_array.
This creates accessor methods to a new instance variable, not to the model attribute type_array, which means that #record.type_array now refers to that instance variable instead of the attribute.
You almost never use attr_accessor or it's siblings attr_reader and attr_writer in Rails because you want to deal with model attributes, not instance variables.
Edit: You're using type_array as a virtual attribute.
class Record < ActiveRecord::Base
validates :type_array, :presence => true
attr_accessible :type_array
def type_array=(val)
self.type_list = val.join ','
end
def type_array
self.type_list.split ','
end
def type_array_before_type_cast
type_array
end
end
For the reason why you need that last function definition, see this question.