Why I need to select image again after validation failed - ruby-on-rails

I have two models
class ComfortFactorSubCategory < ApplicationRecord
has_one :image, as: :imageable, dependent: :destroy
validates :heading, presence: true
accepts_nested_attributes_for :image, :reject_if => lambda { |a| a[:name].blank? }, allow_destroy: true
end
class Image < ApplicationRecord
belongs_to :imageable, polymorphic: true
mount_uploader :name, IconUploader
end
and my admin/comfort_factor_sub_category.rb I have these lines
ActiveAdmin.register ComfortFactorSubCategory do
permit_params do
permitted = [:heading, image_attributes: [:name, :_destroy, :id], additional_instruction_ids: []]
permitted
end
form do |f|
f.inputs do
f.input :heading
f.input :additional_instructions, as: :select, collection: AdditionalInstruction.pluck(:description, :id)
f.fields_for :image do |b|
b.input :name, label: "Image", :as => :file
end
end
f.actions
end
end
when I submit the form with wrong information lets say without heading and validation fail why do I need to select the image again while I did select in first submission

Seems like you need f.hidden_filed :name_cache for caching uploaded file
Take a look at the CarrierWave making uploads work across form redisplays section and upload through accept_nested_attributes_for wiki article

This is constrained by browser for security reasons. It avoids pre-filling the form with the default file object's value when error page is rendered.
This is a detailed excerpt about this.
This however is usually not supported by browsers. The usual
explanation is “security reasons.” And indeed it would be a security
risk if files from the user’s disk were submitted without the user’s
content. It might be all too easy to lure some users into submitting
some password files!
I also found this another answer talking about the same problem with ASP.net framework.

Related

Active admin / Carrierwave multiple image upload

I've been struggling for a week now, I'm trying to create a form inside active_admin where a user can select several pictures, add a description and a title, then submitting his form to create something that would look like a gallery
So far, I have two models created with the commands:
rails g model Gallery title:string description:text
rails g model Image url:text #just in case the user has LOTS of images to upload
Here are how look my models now:
gallery.rb
class Gallery < ApplicationRecord
has_many :images
accepts_nested_attributes_for :images, allow_destroy: true
end
image.rb
class Image < ApplicationRecord
belongs_to :gallery
mount_uploader :image, ImageUploader #Using Carrier Wave
end
admin/gallery.rb
permit_params :title, :description, :images
form html: { multipart: true } do |f|
f.inputs do
f.input :title
f.input :description
f.input :images, as: :file, input_html: { multiple: true }
end
f.actions
end
My problem is that even though my 'image' form shows up, I can't manage to save the images through the other model, nothing gets uploaded inside my 'public/upload' directory, and nothing gets written inside my database.
I can't find anything interesting internet that could solve this problem
Feel free to ask for another file
Any help welcome
permit_params :title, :description, :images
Why :images, I think you meant images_attributes: [:url]?
But that wouldn't work either. I followed the steps here: https://github.com/carrierwaveuploader/carrierwave/issues/1653#issuecomment-121248254
You can do it with just one model
rails g model Gallery title:string description:text url:string
models/gallery.rb
# your url is accepted as an array, that way you can attach many urls
serialize :url, Array
mount_uploaders :url, ImageUploader
Note: Use serialize with Sqlite, For Postgres or some other database capable of handling arrays read: Add an array column in Rails
admin/gallery.rb
permit_params :title, :description, url: []
form html: { multipart: true } do |f|
f.inputs do
f.input :title
f.input :description
f.input :url, as: :file, input_html: { multiple: true }
end
f.actions
end

Rails, Active admin, nested form, dynamic label value - issue with the form object

I have three models:
class Request < ActiveRecord::Base
belongs_to :scenario
belongs_to :location
has_many :actions, :foreign_key => 'request_id'
accepts_nested_attributes_for :actions, :allow_destroy => true
end
class Action < ActiveRecord::Base
belongs_to :request
belongs_to :scenario_step
end
class ScenarioStep < ActiveRecord::Base
belongs_to :scenario
has_many :actions
end
Using Active Admin I want to update information about action taken in response to a request. To do that I am using nested form:
ActiveAdmin.register Request do
permit_params :scenario_id, :location_id,
actions_attributes: [:scenario_step_id, :description]
form(:html => {:multipart => true}) do |f|
f.inputs "Request details" do
f.input :status
panel 'Steps' do
"Text ..."
end
f.has_many :actions, heading: 'Steps to follow', allow_destroy: false, new_record: true do |ff|
ff.input :description, label: ff.object.scenario_step_id, hint: 'Text'
ff.input :scenario_step_id
end
para "Press cancel to return to the list without saving."
f.actions
end
end
end
Everything seems to be fine except of label (or hint). As a value I want to put there related data from a table scenario_steps.
As you can see I currently try to at least print the value of scenario_step_id that should be available in the object form (ff.object.scenario_step_id) but it is not working (I have such column in actions table). On the other hand, next line: ff.input :scenario_step_id loads appropriate data into input field.
Can somebody give ma a hint what am I doing wrong?
Here is what I was missing (part of formtastic documentation):
Values for labels/hints/actions are can take values: String (explicit
value), Symbol (i18n-lookup-key relative to the current "type", e.g.
actions:), true (force I18n lookup), false (force no I18n lookup).
Titles (legends) can only take: String and Symbol - true/false have no
meaning.
So small change (to_s) in line below makes huge difference :)
ff.input :description, label: ff.object.scenario_step_id.to_s, hint: 'Text'

active admin, cannot create nested resource at the same time as the parent

In my app, Invoice has_many Item. So in my active admin UI, I want to be able to create a invoice, and at the same time create its items.
But I can only add items after the invoice is created using the Edit Invoice button in active admin. Trying to create them together will not direct me anywhere from the New Invoice page. And there aren't any errors shown. Could someone help me out on this?
I have the following form structure in my app/admin/invoice.rb
permit_params :paid, :due, :customer_id,
items_attributes: [:price, :description, :invoice_id, :purchased_product_id]
form multipart: true do |f|
f.inputs do
input :customer
input :due
input :paid, as: :radio
end
f.inputs "Items" do
f.has_many :items do |item|
item.input :price
item.input :description
item.input :purchased_product
end
end
f.actions
end
I have added the accepts_nested_attributes_for in my Invoice model as follow:
class Invoice < ActiveRecord::Base
belongs_to :customer
has_many :items
accepts_nested_attributes_for :items, allow_destroy: true
validates :customer, presence: true
I am using Rails 4, and activeadmin '~> 1.0.0.pre1'
The problem is to deal with my validations in my Item model. I had the following validation rule in my Item model class
validates :price, :invoice, presence: true
This says that in order to create an item, it has to have an invoice connected. But since in the creation process of the invoice and its contained items, invoice is yet saved to database. The items can't find an invoice to connect to yet, and the validation failed.
The problem is solved by removing the presence validation of invoice, to
validates :price, presence: true

Validate before Posting a text or an image

I am working on a self-learning Rails application (the source code can be found here. I want to validate the presence of the content before posting a text or an image:
.
Those are my models or look below:
class Post < ActiveRecord::Base
belongs_to :user
default_scope { order ("created_at DESC")}
belongs_to :content, polymorphic: true
has_reputation :votes, source: :user, aggregated_by: :sum
end
class PhotoPost < ActiveRecord::Base
has_attached_file :image, styles: {
post: "200x200>"
}
end
class TextPost < ActiveRecord::Base
attr_accessible :body
end
Here are my controllers in case they have a relation with this. Any other files can be found in my Github account. I am sure it will be messy to copy the whole project (that is why I am giving links for the controllers and for my project).
So what I have tried so far. (I tried those on the Posts Model)
=> Using validates_associated
validates_associated :content, :text_post
and getting an error "undefined method `text_post' for #Post:0x517c848>"
=> Used validates
validates :content, :presence => true
and getting no error however a post is created with no text.
validates :body, :presence => true
and getting an error "undefined method `body' for #Post:0x513e4a8>"
If you need any other information please let me know and I will provide it asap.
Thank you.
It would seem you have quite a confusing model setup with some key missing relation rules. E.g. Polymorphic rule which is not being utilised and a has_many relation between User and Post with no sign a of a user_id value in the Post model. Here is how I would set it up:
User.rb
def User << ActiveRecord::Base
has_many :text_posts
has_many :photo_posts
end
TextPost.rb
def TextPost << ActiveRecord::Base
attr_accessible :body, :user_id
belongs_to :user
validates :body, :presence => true
end
PhotoPost.rb
def PhotoPost << ActiveRecord::Base
attr_accessible :image, :user_id
belongs_to :user
validates :file, :presence => true, :format => {
:with => %r{\.(gif|png|jpg)$}i,
:message => "must be a URL for GIF, JPG or PNG image."
}
end
Then in your view you would need to do:
<%= form_for #text_post do |f| %>
# ...
<% end %>
And in your controller you can modify the create method to include the current_user from devise and assign it to the new text post record (user_id attribute):
text_posts_controller.rb
def create
#text_post = current_user.text_posts.new(params[:text_post])
end
This adheres more to the DRY principle which Ruby on Rails excels at - you shouldn't be writing alot of code to just create a new record.
I would advise on reading up on some Ruby on Rails standard and best practises. You shouldn't need to create a method in the Dashboard Model in order to create a new TextPost or PhotoPost record. This is a very confusing way of going about it; instead you should be utilising the power of ActiveRecord relation.
I would advise checking out Railscasts. They have alot of fulfilling content.

ActiveAdmin forms with has_many - belongs_to relationships?

I have the models Home and Photo, which have a has_many - belongs_to relationship (a polymorphic relationship, but I dont think that matters in this case). I am now setting up active admin and I would like admins to be able to add photos to homes from the homes form.
The photos are managed by the CarrierWave gem, which I dont know if will make the problem easier or harder.
How can I include form fields for a different model in the Active Admin Home form? Any experience doing something like this?
class Home < ActiveRecord::Base
validates :name, :presence => true,
:length => { :maximum => 100 }
validates :description, :presence => true
has_many :photos, :as => :photographable
end
class Photo < ActiveRecord::Base
belongs_to :photographable, :polymorphic => true
mount_uploader :image, ImageUploader
end
Try something like this in app/admin/home.rb:
form do |f|
f.inputs "Details" do
f.name
end
f.has_many :photos do |photo|
photo.inputs "Photos" do
photo.input :field_name
#repeat as necessary for all fields
end
end
end
Make sure to have this in your home model:
accepts_nested_attributes_for :photos
I modified this from another stack overflow question: How to use ActiveAdmin on models using has_many through association?
You could try this:
form do |f|
f.semantic_errors # shows errors on :base
f.inputs # builds an input field for every attribute
f.inputs 'Photos' do
f.has_many :photos, new_record: false do |p|
p.input :field_name
# or maybe even
p.input :id, label: 'Photo Name', as: :select, collection: Photo.all
end
end
f.actions # adds the 'Submit' and 'Cancel' buttons
end
Also, you can look at https://github.com/activeadmin/activeadmin/blob/master/docs/5-forms.md (See Nested Resources)
I guess you are looking for a form for a nested model. Take a look at following railscasts.
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
I cannot tell you much about active_admin, but I think this should not make a difference in handling the nested model.
I have a has_one model, like this:
f.has_many :addresses do |a|
a.inputs "Address" do
a.input :street ... etc.
While this correctly reflects our associations for Address (which is a polymorphic model) using f.has_one fails. So I changed over to has_many and all's well. Except now we have to prevent our users from creating multiple addresses for the same entity.

Resources