Rails - has_many build method not saving association - ruby

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

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

Not null fields for ActiveAttr

I'm having issues enforcing a field to not be nil within ActiveAttr::Model.
Is there an elegant way of enforcing this constraint within the model instead of defining it in the controller? Or am I testing incorrectly for the scenario?
Model:
class Message
include ActiveAttr::Model
attribute :name, :presence => true, :allow_nil => false, :allow_blank => false
attribute :email, :presence => true
attribute :content, :presence => true
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates_length_of :content, :maximum => 500
end
RSpec:
module MessageSpecHelper
def valid_message_attributes
{
:name => "Walter White",
:email => "walter#hailtheking.com",
:content => "I am the one who knocks"
}
end
end
it "should have error on name (alternate with nil)" do
#message.attributes = valid_message_attributes.except(:name => nil)
#message.should have(1).error_on(:name)
end

simple_form, bug with :has_many :through relation?

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

Rails Active Record Validation condition base

class Material < ActiveRecord::Base
belongs_to :material_type
belongs_to :product_review
validates :url, :presence => true, :if => :url_presence?
validates :video, :presence => true, :if => :video_presence?
def url_presence?
if !self.title.blank? and self.material_type.title.eql? :url
true
end
end
def video_presence?
if !self.title.blank? and self.material_type.title.eql? :video
true
end
end
has_attached_file :video,
:url => "/system/video/:id/:attachment/:style/:basename.:extension",
:path => ":rails_root/public/system/video/:id/:attachment/:style/:basename.:extension",
:default_url => "/image/video.png"
end
I assumption if its finds Title fields fill and material_type is url than it perform validation for url field presence validation check, but it not helpful
I think you need to compare strings, not symbols.
validates :url, :presence => true, :if => :url_present?
validates :video, :presence => true, :if => :video_present?
def url_present?
self.title.present? and self.material_type.title == "url"
end
def video_present?
self.title.present? and self.material_type.title == "video"
end

Only validate an Rails3 Model when an value entered

I need to validate a filed called phone_number in my rails3 app. This filed is optional but when a user enter a phone_number i will check the format. The RSpec2 test runs fine but when i go to the sign_up view and don't touch the phone_number field i become an "Phone number is too short (minimum is 6 characters)" and "Phone number is invalid" error.
What is the problem in my model? My target is to validate the phone_number if a user enter this if the number blank i will save an nil in my database.
This is my User model:
class User < ActiveRecord::Base
belongs_to :address
accepts_nested_attributes_for :address
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable, :lockable and :timeoutable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :confirmable, :lockable, :validatable
# Setup accessible (or protected) attributes for your model
attr_readonly :username
attr_accessible :email, :password, :password_confirmation, :remember_me, :phone_number, :username, :newsletter, :address_attributes
validates :username, :presence => true, :uniqueness => true, :length => {:minimum => 4, :maximum => 16 }, :format => { :with => /\A[a-z0-9][a-z0-9._-]*\z/i }
validates :phone_number, :length => {:minimum => 6, :maximum => 25}, :format => { :with => /\A\S[0-9\+\/\(\)\s\-]*\z/i }, :allow_nil => true
validates :address, :presence => true
end
My Rspec Method to test the phone_number:
it "should be valid without an phonenumber" do
Factory.build(:user, :phone_number => nil).should be_valid
end
it "should be invalid with an invalid phonenumber" do
invalid_phonenumbers.each do |invalid|
Factory.build(:user, :phone_number => invalid).should_not be_valid
end
end
it "should be valid with an valid phonenumber" do
valid_phonenumbers.each do |valid|
Factory.build(:user, :phone_number => valid).should be_valid
end
end
def invalid_phonenumbers
["Hans Wurst","+49 221 Hans","Gebe ich nicht ein"," ","110",""]
end
def valid_phonenumbers
["+492203969534","0221/549534","0800-2222 800","+49-0221-2222-390","+49 (221) / 549534 - 23","+49 (0) 221 / 549534 - 23","0221269534"]
end
try this instead of :allow_nil => true, :allow_blank => true
validates :phone_number, :length => {:minimum => 6, :maximum => 25}, :format => { :with => /\A\S[0-9\+\/\(\)\s\-]*\z/i }, :allow_blank => true

Resources