simple_form, bug with :has_many :through relation? - activerecord

I have 3 models like these:
class CertificatorBtwInstructor < ActiveRecord::Base
belongs_to :certificator
belongs_to :instructor
# other code ...
end
class Certificator < ActiveRecord::Base
has_many :btw_instructors, :class_name => "CertificatorBtwInstructor"
has_many :instructors, :through => :btw_instructors
# other code ...
end
class Instructor < ActiveRecord::Base
has_many :btw_certificators, :class_name => "CertificatorBtwInstructor"
has_many :certificators, :through => :btw_certificators
# other code ...
end
on my Instructor new form I have setting:
= simple_form_for( [:cm, #instructor], :html => { :class => "fAdm" } ) do |f|
= f.object.errors
- others fields ...
= f.input :certificator_ids, :required => false, :collection => Certificator.choices_relation_select, :input_html => { :multiple => true, :size => 12 }
%div.row.buttons
= f.button :submit
then, when i submit the form without select any Certificator from the 'certificator_ids' input collection, the new record is created without problem.
But, when I choose any item on the 'certificator_ids' input collection, an error appear (i visualize it with the = f.object.errors ), and the error is this:
{:certificators=>["is not valid"]}
but on my form i haven't setting the field 'certificators', so I don't undestand why they got this attribute.

Change it to
<%= f.association :certificators, :as => :check_boxes %>
this will show to you all your certificators on check boxes, you should take a look at this
https://github.com/plataformatec/simple_form
and this
http://railscasts.com/episodes/47-two-many-to-many

Related

Active admin nested form not working Error: too many arguments for format string

Following is my code block of state Model, SatatImage Model and Active Admin Code. In active admin when I try to create a new record or Edit a --record that time I show an error on production server. but works on my localhost in development mode,
---------Error---------------------------
too many arguments for format string
app/admin/state.rb:49:in `block (2 levels) in '
I am using Ruby 1.9, Rails 3,2, activeadmin (0.6.0)
======State Model===============
class State < ActiveRecord::Base
attr_accessible :name, :code
validates :code, :uniqueness => true
has_one :state_image, :dependent => :destroy
accepts_nested_attributes_for :state_image, :allow_destroy => true
.......
end
==============StatImage Model=============
class StateImage < ActiveRecord::Base
attr_accessible :state_id, :stateimage, :image_name
belongs_to :state
mount_uploader :stateimage, StateUploader
end
=======Active Admin part=================
ActiveAdmin.register State do
.....
form(html:{multipart:true}) do |f|
f.inputs "State Form" do
f.input :name, required:true
f.input :code, required:true
end
#line-49#
f.inputs "StateImage", for:[:state_image, f.object.state_image || StateImage.new] do |p|
p.input :stateimage, :as => :file, :label => "Image"
end
f.buttons :submit
end
end
I am using
f.semantic_fields_for
And Formtastic requires you to wrap ALL inputs in an "inputs" block. So this should be:
f.inputs 'State Image' do
f.semantic_fields_for :state_image, (f.object.state_image || StateImage.new) do |p|
p.inputs do
p.input :stateimage, :as => :file, :label => "Image"
p.input :_destroy, :as => :boolean, :required => false, :label => 'Remove image'
end
end
end
Please try this:
form :html => { :enctype => "multipart/form-data" } do |f|
Also upgrade you activeadmin version to 0.6.6

Rails - has_many build method not saving association

I'm having some trouble trying to make association works.
My models looks like:
advertise.rb
class Advertise < ActiveRecord::Base
belongs_to :user
belongs_to :country
has_many :targets
# has_many :hss, :through => :targets
validates :description, :presence => true
validates :url, :presence => true
validates :country_id, :presence => true
validates :kind, :presence => true
attr_accessible :description, :hits, :url, :active, :country_id, :kind
KINDS = {
'1' => 'Commoditie',
'2' => 'Service',
}
HS = {
'1' => 'Section',
'2' => 'Chapter',
'4' => 'Heading',
'5' => 'SubHeading 1',
'6' => 'SubHeading 2',
}
end
hs.rb
class Hs < ActiveRecord::Base
attr_accessible :code, :kind
has_many :targets
has_many :advertises, :through => :targets
end
target.rb
class Target < ActiveRecord::Base
attr_accessible :advertise_id, :hs_id
belongs_to :advertise
belongs_to :hs
end
advertises_controller.rb
def new
#advertise = Advertise.new
#countries = Country.all
end
def create
#advertise = current_user.advertises.build(params[:advertise])
if #advertise.save
flash[:notice] = 'Advertise created with successful'
redirect_to root_path
else
render :new
end
end
the form for creating a new Ad.
/advertises/new.html.haml
%table.table.table-striped
%tr
%td{:colspan => 2}= advertise.input :url, :required => true
%tr
%td{:colspan => 2}= advertise.input :description, :required => true, :as => :text, :input_html => { :cols => 50, :rows => 3 }
%tr
%td{:colspan => 2}= advertise.input :country_id, :collection => #countries, :as => :select, :label => 'Origin', :required => true
%tr
%td{:colspan => 2}= advertise.input :kind, :collection => Advertise::KINDS.map(&:reverse), :as => :select, :label => 'Type', :required => true
%tr
%td{:colspan => 2}= advertise.input_field :active, as: :boolean, inline_label: 'Active'
=fields_for :targets do |target|
%tr
%td= select_tag :hs_kind, options_for_select(Advertise::HS.map(&:reverse).insert(0,'') )
%td= target.select :hs_id, ''
The hash params:
[3] pry(#<AdvertisesController>)> params
=> {"utf8"=>"✓",
"authenticity_token"=>"fOdn4NYLg/4HXruWURZPf9DYVT4EQzbaTRTKZvX1ugY=",
"advertise"=>
{"url"=>"http://test.com",
"description"=>"test",
"country_id"=>"17",
"kind"=>"2",
"active"=>"1"},
"hs_kind"=>"2",
"targets"=>{"hs_id"=>"487"},
"commit"=>"Create Advertise",
"action"=>"create",
"controller"=>"advertises"}
The hash seems ok to me, but it creates only the Advertise, and not creates the target for the advertise associated.
Any though? Maybe a wrong model association.
Thanks in advance.
try changing
=fields_for :targets do |target|
to
= advertise.fields_for :targets do |target|
and add the following to advertise.rb
accepts_nested_attributes_for :targets
attr_accessible :targets_attributes # just add targets_attributes to attr_accessible
be warned that when you do this, advertise objects that has no targets will not show the fields for targets. you have to build a new target object associated to advertise in order to show the fields
# example: on the new action of the controller
#advertise = Advertise.new
#advertise.targets.build

Why is assign_attributes with array of ids for has_many association only associating one object?

I have a form where users can upload assets using ajax. This creates many Asset objects that I then want to associate with a Post object when it is created. I have a form_field named asset_ids that I update with the created Asset ids as they are created. When I create the Post object and populate its data with assign_attributes, only ONE association is created, no matter how many ids are there.
Asset model:
class Asset < ActiveRecord::Base
attr_accessible :caption, :image
belongs_to :post
has_attached_file :image, :styles => { :large => "600x600>", :medium => "300x300>", :thumb => "100x100>" }
end
Post model:
class Post < ActiveRecord::Base
attr_accessible :content, :post_date, :status, :title, :tag_list, :asset_ids, :as => :admin
has_many :assets, :dependent => :destroy
has_and_belongs_to_many :tags
validates :content, :post_date, :title, :presence => true
end
An example of the posted data hash:
{"title"=>"Test post", "status"=>"true", "post_date"=>"01/02/2013", "content"=>" Some content", "tag_list"=>"", "asset_ids"=>"97,102"}
The example above assigns only one Asset (id 97) to the new Post, when I assign_attributes like so:
#post = Post.new
#post.assign_attributes params[:post], :as => :admin
I had to make sure I was assigning the ids as an array:
#post.asset_ids = params[:post][:asset_ids].split(",")

Rails 3 Polymorphic Associations, User model with multiple content items?

In Rails 3 I'm trying to model a user content system, where the user can post different types of content, for example, note, photo, url etc.
From a Java/C# OO perspective, I would use a polymorphic relationship between the User and an interface representing a Content item, e.g. something called IUserContent.
I'm struggling to find an example that works how I expect it to, here's what I tried first, in short I'm getting confused about the implementation of polymorphic associations in ActiveRecord.
# user.rb model - includes...
has_many :notes, :as => :postable, :dependent => :destroy, :inverse_of => :postable
has_many :urls, :as => :postable, :dependent => :destroy, :inverse_of => :postable
has_many :photos, :as => :postable, :dependent => :destroy, :inverse_of => :postable
# url.rb ...
belongs_to :postable, :polymorphic => true, :inverse_of => :urls
# photo.rb
belongs_to :postable, :polymorphic => true, :inverse_of => :photos
# note.rb
belongs_to :postable, :polymorphic => true, :inverse_of => :notes
I'm still just following examples I've found, and frankly this feels like User is the polymorphic target, not the content.
I think I want something like this...
# within user.rb
has_many :postable, :as => :postable, dependent => :destroy, :inverse_of => :users
# photo.rb
# url.rb
# note.rb
# all have the following...
belongs_to :user, :polymorphic => true, :inverse_of => :postable
... looking for a few pointers in the right direction.
Thank you.
The only way you can do that is if all of these classes inherit from the same base class, as in:
class User < ActiveRecord::Base
has_many :postable, :as => :postable, :dependent => :destroy, :class_name => 'Postable'
end
class Postable < ActiveRecord::Base
belongs_to :user, :polymorphic => true
end
class Photo < Postable
end
class Url < Postable
end
class Note < Postable
end
So, you have to use the ActiveRecord single-table inheritance to model such a relationship.

How do I abstract similar validations/relations to parent class in Ruby/Rails?

I have these VERY similar classes:
class DeliveryDocument < CommercialDocument
# Relations
belongs_to :biller, :class_name => 'Company'
belongs_to :customer, :class_name => 'Company'
belongs_to :customer_center, :class_name => 'Center'
has_many :delivery_document_lines, :dependent => :destroy
alias_attribute :lines, :delivery_document_lines
# Some configuration
accepts_nested_attributes_for :delivery_document_lines
acts_as_freezable :only_dependencies => true,
:has_many => [:delivery_document_lines],
:belongs_to => [:biller, :customer, :customer_center]
acts_as_clonable :has_many => [:delivery_document_lines]
validates_each :lines do |record, attr, value|
# ...
end
end
And:
class InvoiceDocument < CommercialDocument
self.
# Relations
belongs_to :biller, :class_name => 'Company'
belongs_to :customer, :class_name => 'Company'
belongs_to :customer_center, :class_name => 'Center'
has_many :invoice_document_lines, :dependent => :destroy
alias_attribute :lines, :invoice_document_lines
# Some configuration
accepts_nested_attributes_for :invoice_document_lines
acts_as_freezable :only_dependencies => true,
:has_many => [:invoice_document_lines],
:belongs_to => [:biller, :customer, :customer_center]
acts_as_clonable :has_many => [:invoice_document_lines]
# Validations
validates_each :lines do |record, attr, value|
# ...
end
end
I also have some methods I didn't paste that could be extracted to the parent. I only need to know the class name in the parent. When I do this:
class CommercialDocument < Document # document inherits from AR::Base
# ...
has_many :"#{self.to_s.underscore}_lines", :dependent => :destroy
# ...
accepts_nested_attributes_for :"#{self.to_s.underscore}_lines"
# ...
end
it doesn't work, because self.to_s is CommercialDocument.
How would you refactor this behavior in parent class?
I could put things in a module and import it, but then the whole hierarchy of documents becomes almost useless.
I already have the documents' hierarchy, so if I can, I want to use it if there is a way.
You could try using Class.inherited

Resources