form.html.haml not rendering on new.html.haml - ruby

I'm working from the book 'Agile Web Development with Rails 4' and I'm having some difficulty with my HAML code.
I'm not too sure what I've done wrong, but my form isn't rendering when I go to build a new product. I check the source code and it's not in the HTML either so something is wrong with my code but not sure what. Hopefully someone can help me.
This is my code for Form.html.haml
=if #product.errors.any?
%div{ :id => "error_explanation" }
%h2
=pluralize(#product.errors.count, "error")
prohibited this product from being saved:
%ul
=#product.errors.full_messages.each do |msg|
%li
=msg
%div{ :class => "field" }
=f.label :title
=f.text_field :title
%div{ :class => "field" }
=f.label :description
=f.text_area :description, rows: 6
%div{ :class => "field" }
=f.label :image_url
=f.text_field :image_url
%div{ :class => "field" }
=f.label :price
=f.text_field :price
%div{ :class => "actions" }
=f.submit
And this is my New.html.haml
%h1 New Product
=render 'form'
=link_to 'Back', products_path
Thank you in advance.

According to the answers provided by meagar and theTRON as well as your last comment:
Where are you bringing to light the form object? It seems like nowhere, thus you are getting that error. When you bind a form to a model object through the form_for method, it yields a form builder object (the f variable).
Try something like the following:
<%= form_for #product, url: {action: "create"} do |f| %>
# your code using f variable ...
<% end %>
Let us know if that finally fixed your code.

Partials need to be named with an _ prefix.
Your Form.html.haml must be called _form.html.haml.

In addition to ensuring that your form is named _form.html.haml you'll need to fix some nesting in your HAML. It should look something like this instead:
=if #product.errors.any?
%div{ :id => "error_explanation" }
%h2
=pluralize(#product.errors.count, "error")
prohibited this product from being saved:
%ul
=#product.errors.full_messages.each do |msg|
%li
=msg
%div{ :class => "field" }
=f.label :title
=f.text_field :title
%div{ :class => "field" }
=f.label :description
=f.text_area :description, rows: 6
%div{ :class => "field" }
=f.label :image_url
=f.text_field :image_url
%div{ :class => "field" }
=f.label :price
=f.text_field :price
%div{ :class => "actions" }
=f.submit
Your indentation that you currently have on your form fields placed it in the scope of the if #product.errors.any? block, which means the form would only appear if #product had errors.

Related

upload image and files padrino

i want to put index image to my blog's posts
and have an upload form in 'new post 'in admin's panel
the form is written like this :
- error = #post.errors.include?(:file)
%fieldset.control-group{:class => error ? 'has-error' : ''}
=f.label :file, :class => 'control-label'
.controls
=f.file_field :file ,:name => 'file'
- error = #post.errors.include?(:title)
%fieldset.control-group{:class => error ? 'has-error' : ''}
=f.label :title, :class => 'control-label'
.controls
=f.text_field :title, :class => 'form-control input-large input-with-feedback', :autofocus => true
%span.help-inline=error ? f.error_message_on(:title, :class => 'text-error') : pat(:example)
- error = #post.errors.include?(:body)
%fieldset.control-group{:class => error ? 'has-error' : ''}
=f.label :body, :class => 'control-label'
.controls
~f.text_area :body, :class => 'form-control input-large input-with-feedback'
%span.help-inline=error ? f.error_message_on(:body, :class => 'text-error') : pat(:example)
.form-actions
=f.submit pat(:save), :class => 'btn btn-primary'
=f.submit pat(:save_and_continue), :class => 'btn btn-info', :name => 'save_and_continue'
=link_to pat(:cancel), url(:posts, :index), :class => 'btn btn-default'
but i don't know what i must do in functions to save file .
An easy-to-follow guide (assuming you are using activerecord. otherwise change 1st line on example).
Add carrierwave to your Gemfile, and execute bundle install.
Generate a migration: padrino g AddImageToPosts image:string and execute it.
Add mount_uploader :image, Uploader to your Post model.
Inside your lib folder create a file, named uploader.rb (or whatever, but then do not forget to change Uploader on 3rd step.)
Add lines from 7 to 83 to uploader.rb (do not forget uncomment lines, and fix them so they to match your needs).
Browse admin, click browse button for file upload - select a file from filesystem - you are done.
example (step 3)
require 'carrierwave/orm/activerecord'
class Post < ActiveRecord::Base
belongs_to :category
mount_uploader :image, Uploader
...
end

Form not saving if try to upload image with Paperclip

so paperclip, seems as if there is a different way to get it working every time i use it.
So at the moment i try and submit a form but it fails and re renders the form (which is what its supposed to do if the form does not save).
This is my setup so far
Gemfile
gem "paperclip", "~> 3.0"
Controller
def new
#post = Post.new
end
def create
#user = current_user
#post = #user.posts.new(params[:post])
if #post.save
redirect_to root_path, :notice => 'Post Successfully Created'
else
render :action => 'new'
end
end
Post Model
class Post < ActiveRecord::Base
belongs_to :category
belongs_to :user
attr_accessible :comments, :title, :category_id, :user_id, :photo
has_attached_file :photo, :styles => { :medium => "300x300>", :thumb => "100x100>" }
end
Form
<%= form_for #post, :class => 'post-form', :html => { :multipart => true } do |f| %>
<%= f.label :title, "Title", :class => 'title_label' %>
<%= f.text_field :title %>
<%= f.label :category_id, "Choose Category", :class => 'title_label' %>
<%= f.collection_select(:category_id, Category.all, :id, :name, :prompt => "Please Select a Category") %>
<%= f.label :comments, "Comments", :class => 'title_label' %>
<%= f.text_area :comments %><br>
<%= f.file_field :photo %>
<%= f.submit 'Submit', :class => 'btn' %>
<% end %>
My migration to add photo was successful as my schema looks like so
create_table "posts", :force => true do |t|
t.string "title"
t.text "comments"
t.integer "category_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "photo_file_name"
t.string "photo_content_type"
t.integer "photo_file_size"
t.datetime "photo_updated_at"
end
Can anyone see reason why this is not working as expected?
EDIT
Do i need ImageMagick installed to allow the upload of an image or is this just for rendering an image in the view?
ok so from the comments i have started to try and debug and put this in my view
<%= #post.errors.full_messages %>
I get this returned
["Photo C:/Users/RICHAR~1/AppData/Local/Temp/bitman20130724-5600-agvtgn.png is not recognized by the 'identify' command.", "Photo C:/Users/RICHAR~1/AppData/Local/Temp/bitman20130724-5600-agvtgn.png is not recognized by the 'identify' command."]
Any ideas?
Thanks
Step 1
From paperclip documentation:
ImageMagick must be installed and Paperclip must have access to it. To ensure that it does, on your command line, run which convert (one of the ImageMagick utilities). This will give you the path where that utility is installed. For example, it might return /usr/local/bin/convert.
Then, in your environment config file, let Paperclip know to look there by adding that directory to its path.
In development mode, you might add this line to config/environments/development.rb:
Paperclip.options[:command_path] = "/usr/local/bin/"
Step 2
For agvtgn.png is not recognized by the 'identify' command. error:
Not sure how you do this in windows, for linux this is what you need to do:
$ which identify
/path/to/identify
Set command_path to that path in config/environments/development.rb:
Paperclip.options[:command_path] = "/path/to"
also you need ImageMagick to be installed
http://ganeshprasadsr.blogspot.com/2010/12/paperclip-issue-is-not-recognized-by.html
What I think - You just need to install ImageMagick.
p.s. Windows is the worst development machine. You could install at least a virtual machine running on linux.

how to create a submit button in a modal?

I have created a normal
= simple_form_for #nacform, :html => { :multipart => true } do |f|
= f.error_notification
.row
.span12
%h4 Form Details
%hr
.row
.span3
.field
= f.input :Title
.field
= f.input :Description
.field
= f.label :asset, "File"
= f.file_field :asset
.form-actions
= link_to 'Back', nacforms_path, :class => 'btn btn-small btn-primary'
%a#modal_btn.btn.btn-success.btn-small{:href => "#modal"} Continue
and the modal
#modal.modal.hide
.about
.modal-header
%button.close{"aria-hidden" => "true", "data-dismiss" => "modal", :type => "button"} ×
%h2 Forms
= simple_form_for #nacform, :html => { :multipart => true } do |f|
= f.button :submit, "Upload Form", :class => 'btn btn-success'
:javascript
$("#modal_btn").click(function(){
$('#modal').modal();
});
the submit button for the form is on the modal, but when i click on that submit button nothing happens, Am I doing it wrong ?
In order for things to appear using jQuery show method or something derived from it, you generally specify an inline style that's easy to override:
#modal.modal{ :style => 'display:none' }
Having a .hide CSS class may be what's causing it to stay hidden.

Several polymorphic associations using class_name?

I am trying to create an article which holds in_prices and out_prices (one for each country) using rails polymorphic associations and nested forms.
I have a data model which looks something like this:
# app/models/article.rb
class Article < ActiveRecord::Base
has_many :out_prices, :class_name => "Price", :as => :priceable
has_many :in_prices, :class_name => "Price", :as => :priceable
end
# app/models/price.rb
class Price < ActiveRecord::Base
belongs_to :priceable, :polymorphic => true
end
# db.schema for prices
create_table "prices", :force => true do |t|
t.integer "value"
t.integer "country_id"
t.integer "priceable_id"
t.string "priceable_type"
end
The article and its associations are created using a nested form like:
# app/views/articles/_article_form.html.erb
<%= form_for setup_article(#article) do |f| %>
<%= f.fields_for :in_prices do |ff| %>
<%= ff.text_field :value %>
<% end %>
<%= f.fields_for :out_prices do |ff| %>
<%= ff.text_field :value %>
<% end %>
<% end %>
The setup_article method is a helper method to build the associations:
# app/helpers/articles_helper.rb
def setup_article(article)
if article.in_prices.nil?
# Setup one in price for each country
Country.all.each do |country|
article.in_prices.build(:value => 0, :country_id => country.id)
end
end
if article.out_prices.nil?
# Setup one out price for each country
Country.all.each do |country|
article.out_prices.build(:value => 0, :country_id => country.id)
end
end
article
end
setup_article is needed to make sure empty price form fields (one for each country) shows up when creating a new article.
Now to the actual problem. When I edit an already created Article (which have associated in_prices and out_prices) Rails won't be able to differentiate between these different types of polymorphic associations (in_prices and out_prices). Because of this both nested form helpers renderes form fields for all associated prices, which isn't the desired behavior. I only want to list in_prices in the one of the nested forms, and the out_prices in the other.
How should these associations be configured to make sure rails can differentiate between the in_prices and out_prices associations in the two different nested form helpers?
EDIT (SOLVED)
A friend of mine pointed out I need to add yet another field in the prices table to flag what type of price it is. I called this field price_type and the db.schema ended up looking like this:
# db.schema for prices
create_table "prices", :force => true do |t|
t.integer "value"
t.integer "price_type"
t.integer "country_id"
t.integer "priceable_id"
t.string "priceable_type"
end
Note: Don't name this field 'type' since this is a reserved name.
The 'price_type' field can be populated either by adding a hidden field in the nested forms (less safe), or to handle it in the controller before saving the article and its associated data. I chose to add it as hidden params like:
# app/views/articles/_article_form.html.erb
<%= form_for setup_article(#article) do |f| %>
<%= f.fields_for :in_prices do |ff| %>
<%= ff.text_field :value %>
<%= ff.text_field :price_type, :value => "in" %>
<% end %>
<%= f.fields_for :out_prices do |ff| %>
<%= ff.text_field :value %>
<%= ff.text_field :price_type, :value => "out" %>
<% end %>
<% end %>
To make sure the associations gets filtered correctly they need to be declared with the ':conditions' tag, like:
# app/models/article.rb
class Article < ActiveRecord::Base
has_many :out_prices, :class_name => "Price", :as => :priceable, :conditions => { :price_type => "in" }
has_many :in_prices, :class_name => "Price", :as => :priceable, :conditions => { :price_type => "out" }
end
.. and now everything works as expected. cheers!

Using ClientSideValidations gem inside ajax rendered partial

I am currently using the ClientSideValidations gem and stuck while rendering a partial using ajax and trying to validate addresses inside that rendered partial with the gem mentioned above. Nothing happens when entering a wrong combination specified in the model.
If browsing to the address-form directly and trying out validations, everything works fine, just like specified.
Any hints or thoughts on how to make the validations gonna work inside the partial?
Thanks!
EDIT: No errors in JS console, just nothing happens when for example entering a too short zipcode (specified in the model with 5 digits). Btw I use haml for the views.
So the code in my view:
= link_to "Shipping", addresses_path, :remote => true
corresponding controller addresses_controller.rb
respond_to do |format|
...
format.js {render :layout => false}
...
end
corresponding index.js.erb
$("#ajax_content").html("<%= escape_javascript(render :partial =>
"partialXY") %>");
and corresponding partial
= form_for #address, :validate => true, :id => "address_form", :remote => true do |f|
- if #address.errors.any?
#error_explanation
%h2
= pluralize(#address.errors.count, "error")
prohibited this user from being saved:
%ul
- #address.errors.full_messages.each do |msg|
%li
=msg
%ul
%li
= f.label :type
= f.select :address_type, [['Billing Address', 'billing'],['Shipping Address',
'shipping']], :class => "address_selection"
%li
= f.label :gender
= f.select :gender, [['Male', 'male'],['Female', 'female']], :class => "text_field"
%li
= f.label :last_name
= f.text_field :last_name, :id => "last_name", :class => "text_field"
%li
= f.label :first_name
= f.text_field :first_name, :class => "text_field"
%li
= f.label :company_name
= f.text_field :company_name, :class => "text_field"
%li
= f.label :street
= f.text_field :street, :class => "text_field"
%li
= f.label :number
= f.text_field :number, :class => "text_field"
%li
= f.label :zipcode
= f.text_field :zipcode, :class => "text_field"
%li
= f.label :place
= f.text_field :place, :class => "text_field"
%li
= f.label :phone_no
= f.text_field :phone_no, :class => "text_field"
%li
= f.label :country
= f.text_field :country, :class => "text_field"
%li
= f.label :email
= f.text_field :email, :class => "text_field"
%li
= f.submit
so like I said nothing happens when validating the rendered partial inputs like zipcode, etc. The funny thing is, that if you look at the following, automatically by rails generated view for editing addresses, the validation works just fine.
rails generated view to edit address
=render 'partialXY'
I have been working on this issue for a long time and have absolutely no clue on how to fix this. I'm sure it has something to do with ajax since using validation when rendering the rails generated partial works just fine.
Thanks a lot! Phil
Ok I fixed it. Turned out despite giving the form an ID, the ID was a different one in the final html code. So I just added a
$('form.form_real_id').validate();
to my .js.erb file!

Resources