Rails Cocoon read only fields - ruby-on-rails

I am using Cocoon for nested forms. For task records that are already created, I want description to be read_only.
projects/_form::
= simple_form_for #project do |f|
= f.input :name
= f.input :description
%h3 Tasks
#tasks
= f.simple_fields_for :tasks do |task|
= render 'task_fields', f: task
.links
= link_to_add_association 'add task', f, :tasks
= f.submit
And _task_fields :
.nested-fields
- if #task.description?
= f.text_field :description, disabled: true
- else
= f.input :description
= f.input :done, as: :boolean
= link_to_remove_association "remove task", f
Currently the validation in _task_fields is not working: undefined method <description> for nil:NilClass in the line with if statement. How can I write the IF statement correctly?

For task records that are already created, I want description to be
read_only.
You are doing it wrong. You should be able do the check by using new_record? like so
.nested-fields
- unless f.object.new_record?
= f.text_field :description, disabled: true
- else
= f.input :description
= f.input :done, as: :boolean
= link_to_remove_association "remove task", f
Also, by using disabled: true, the value of description won't be submitted and cannot be passed through params. If you want to have the description value in the params, use readonly: true instead.
.nested-fields
- unless f.object.new_record?
= f.text_field :description, readonly: true
- else
= f.input :description
= f.input :done, as: :boolean
= link_to_remove_association "remove task", f

Related

cocoon rails, how to get atached file name

Im using cocoon to attach files. I need to be able to remove file when editing a question. Im stuck on getting the exact file name to remove when rendering edit
div.edit_question
=form_for #question, remote: true do |f|
= f.label :title, class: 'label_hidden'
= f.text_field :title
br
= f.label :body, class: 'label_hidden'
= f.text_area :body
br
= f.fields_for :attachments do |f|
.nested-fields
= link_to_remove_association "remove #{ NAME HERE }", f
br
= f.submit 'Update'
Case is closed ))
=form_for #question, remote: true do |f|
= f.label :title, class: 'label_hidden'
= f.text_field :title
br
= f.label :body, class: 'label_hidden'
= f.text_area :body
br
- #question.attachments.each do |att|
= f.fields_for att do |f|
.nested-fields
= link_to_remove_association "remove #{ att.file.filename }", f
br
= f.submit 'Update'

Rails simple_form error: false

in my app I have form that looks like this
= simple_form_for #user do |f|
= f.input :name, error: false
= f.input :surname, error: false
Is there any way to avoid this repetitions (error: false)?
If they're all of the same type, something like this should work:
= simple_form_for #user do |f|
- [ :name , :surname ].each do |field|
= f.input field, error: false
If not, you could use a hash or something, instead of an array, and specify the type, as well.
It appears that simple form has the following option:
If you want to pass the same options to all inputs in the form (for
example, a default class), you can use the :defaults option in
simple_form_for. Specific options in input call will overwrite the
defaults:
<%= simple_form_for #user, defaults: { input_html: { class: 'default_class' } } do |f| %>
<%= f.input :username, input_html: { class: 'special' } %>
<%= f.input :password, input_html: { maxlength: 20 } %>
<%= f.input :remember_me, input_html: { value: '1' } %>
<%= f.button :submit %>
<% end %>
From https://github.com/plataformatec/simple_form
So, in your case:
= simple_form_for #user , defaults: { error: false } do |f|
= f.input :name
= f.input :surname
You could loop through an array of symbols
simple_form_for #user do |f|
[:name, :surname].each do |element|
f.input element, error: false
end
end

Rails 4 yield additional form fields

I'm trying to DRY up one of my forms that sometimes has additional fields (for nested models) when making a new entry, but wouldn't need those fields when performing an update. As such, I was trying to pass the additional fields in via a block, but the form object isn't being passed properly.
Is there a way to pass a form object (or really any variable) into a yield?
Example code for reference:
_form.slim
= nested_form_for #model do |f|
.row
= f.label :name
= f.text_field :name, autofocus: true
...
= yield
...
= f.submit 'Save'
new.html.slim
== render layout: 'model/form' do
h3 Additional Fields
= f.fields_for :nested do |h|
= a.label :name, 'Nested Name'
= a.text_field :name
= a.link_to_remove do
= fa_icon 'times-circle-o'
= f.link_to_add "Add another nested model", :nested
edit.html.slim
== render layout: 'model/form'
To elaborate on my comment, this is how I'd do it using partials:
_form.slim
= nested_form_for #model do |f|
.row
= f.label :name
= f.text_field :name, autofocus: true
...
- if defined?(additional_fields)
h3 Additional Fields
= f.fields_for :nested do |h|
= a.label :name, 'Nested Name'
= a.text_field :name
= a.link_to_remove do
= fa_icon 'times-circle-o'
= f.link_to_add "Add another nested model", :nested
...
= f.submit 'Save'
new.html.slim
== render 'model/form', :additional_fields => true
edit.html.slim
== render 'model/form'
I might be missing something, but I'm not sure why this wouldn't work.

Rails 3.2 validating string inclusion default value not detected

I am using mongoid with a model field and given validation:
field :status, type:String, :default=>'Active'
validates :status, :inclusion=>{:in=>%w(Active, Done, Canceled, Merged)}, :allow_nil=>true, :allow_blank=>true
in the form, I do not have the status field, so it's supposed to be not POST-ed therefore it's nil on creation:
= simple_form_for([#user, #task], :html => {:class=>'form-horizontal',:'data-type'=>'html'}) do |f|
- if #task.errors.any?
.error_explanation
.alert.alert-error
The form contains
= pluralize(#task.errors.count, 'error')
%ul
- #task.errors.full_messages.each do |msg|
%li=msg
.form-inputs
= f.error_notification
= f.association :project, :collection => current_user.projects.all
= f.input :description, :as => :text, :input_html => {:rows => 5}
= f.input :priority, :as=>:radio_buttons, :collection=>1..4, :item_wrapper_class=>'inline'
= f.input :due_date
.control_group.select.optional
= f.label :assigned_to, :class=>'select optional control-label', :for => 'assigned_to_id'
.controls
= f.collection_select :assigned_to_id, User.all, :id, :username, :class => 'select optional'
.form-actions
= f.button :submit, :class => 'form-button btn-primary', 'data-loading-text' => 'Submitting...'
however, I am still getting this despite setting a default value "Active", which is obviously in the array provided for the validation of inclusion:
Status is not included in the list
why am I still getting this error?
Thanks in advance!
This is your issue
%w(Active, Done, Canceled, Merged)
which translates to
["Active,", "Done,", "Canceled,", "Merged"]
solution is to remove the commas
%w(Active Done Canceled Merged)

Rails - undefined method `each' for 0:Fixnum

I get the following error in Ruby on Rails undefined method 'each' for 0:Fixnum.
Here is the application trace :
app/controllers/videos_controller.rb:23:in `new'
app/controllers/videos_controller.rb:23:in `create'
And my controller create and new actions :
def new
#video = Video.new
end
def create
method = 'get_' + params[:video][:provider] + '_video_id'
params[:video][:provider_video_id] = Video.send(method, params[:video][:url])
params[:video][:thumb] = Video.get_thumb_from_youtube(params[:video][:provider_video_id])
params[:video][:views] = params[:video][:likes] = 0
params[:video][:user_id] = current_user
#video = Video.new(params[:video])
if #video.save
redirect_to video_path(#video), notice:'Video added successfully.'
else
render :new
end
end
Here is my view.html.haml :
= form_for #video do |f|
- if #video.errors.any?
.error_explanation
%h2= pluralize(#video.errors.count, "error")
prohibited this user from being saved:
%ul
- #video.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :title
= f.text_field :title
.field
= f.label :description
= f.text_area :description
%br
.field
= f.label :url, 'URL'
= f.text_field :url
%br
.field
Provider
= radio_button :video, :provider, 'vimeo'
= f.label :provider, 'Vimeo', :value => 'vimeo'
= radio_button :video, :provider, 'youtube'
= f.label :provider, 'Youtube', :value => 'youtube'
%br
.field
Category
= collection_select(:video, :category_id, Category.all, :id, :name, :include_blank => true)
%br
.actions
= f.submit "Add video"
From
params[:video][:views] = params[:video][:likes] = 0
to
params[:video][:views] = 0
I assume that video.likes is an association, not a count, so it expects an Enumerable. If it's an association, rails tries to assign the elements you add to likes to your video model. The first step of adding them is to iterate - using each. That's where the error comes from.

Resources