Rails posts show up blank, not saving - ruby-on-rails

I tried to submit a new post and I get the error
"Title can't be blank"
So I removed the validations in my model and after trying again and posting something, the post is just blank, no data is saved whatsoever.
I don't know what to do, I stuck on this one, help!
Update!
Here is the form
<% #post.tags.build %>
<%= form_for #post, :html => {:multipart => true } do |post_form| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved: </h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= post_form.file_field :photo %>
</div>
<div class="field">
<%= post_form.label :title %><br />
<%= post_form.text_field :title %>
</div>
<div class="field">
<%= post_form.label :url %><br />
<%= post_form.text_field :url %>
</div>
<div class="field">
<%= post_form.label :company %><br />
<%= post_form.text_field :company %>
</div>
<div class="field">
<%= post_form.label :language %><br />
<%= post_form.text_field :language %>
</div>
<div class="field">
<%= post_form.label :framework %><br />
<%= post_form.text_field :framework %>
</div>
<div class="field">
<%= post_form.label :details %><br />
<%= post_form.text_area :details %>
</div>
<h2>Tags</h2>
<%= render :partial => 'tags/form' ,
:locals => {:form => post_form } %>
<div class="actions">
<%= post_form.submit %>
</div>
<% end %>
here is the controller:
class PostsController < ApplicationController
http_basic_authenticate_with :name => "franklinexpress", :password => "osxuser8", :except => [:index, :show, :new, :edit]
#def search
# #posts = Post.search(params[:search])
# end
# GET /posts
# GET /posts.json
def index
#posts = Post.search(params[:search])
# #posts = Post.all
# respond_to do |format|
#format.html # index.html.erb
#format.json { render json: #posts }
#end
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #post }
end
end
# GET /posts/new
# GET /posts/new.json
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.json
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :ok }
end
end
end
in my model:
class Post < ActiveRecord::Base
validates :title, :presence => true
validates :url, :presence => true
validates :company, :presence => true
validates :language, :presence => true
validates_attachment_size :photo, :less_than => 4.megabytes
validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/png']
has_many :comments, :dependent => :destroy
has_many :tags
attr_accessor :photo_file_name
attr_accessor :photo_content_type
attr_accessor :photo_file_size
attr_accessor :photo_updated_at
attr_accessible :photo
accepts_nested_attributes_for :tags, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
#paperclip-------------------------------
has_attached_file :photo,
:url => "/assests/images/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/images/:id/:style/:basename.:extension"
#:style => {:small => "150x200>"}
def self.search(search)
if search
where('title LIKE ?', "%#{search}%")
# find(:all, :conditions => ['title LIKE ?', "%#{search}%"])
else
all
end
end
end
and in new.html.erb:
<div id="header-wrap">
<%= image_tag("walLogotiny.png") %>
<div id="searchbartop">
<%= form_tag posts_path, :method => :get do%>
<%= text_field_tag :search, params[:search] ,"size" => 100 %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</div>
</div>
<div id="container">
<h2>New Site Submission</h2>
<%= render 'form' %>
<%= link_to 'Back', posts_path %>
</div>

With this line in your model:
attr_accessible :photo
You make only the photo attribute mass-assignable. All other attributes, including the title, are dropped when you create a new post.
Try this:
attr_accessible :photo, :title
It will now accept the title, but not the other attributes.
edit: didn't see your own comment above, but you figured it out already.

Related

Rails Paperclip Gem Saving Multiple Attachments per Model instance

I'm very new to Rails development and having a problem saving multiple images/attachments to a model. My problem is that the code below is not actually saving to the item_images table when I submit the form. I am following This Article as a guide, though it seems to be a bit out of date. I feel I'm in a little over my head at this point so I hope someone can point out what I'm missing. Thanks!
I have the following models:
item.rb
class Item < ActiveRecord::Base
has_many :item_images, :dependent => :destroy
accepts_nested_attributes_for :item_images, :reject_if => lambda { |t| t['item_image'].nil? }
end
item_image.rb
class ItemImage < ActiveRecord::Base
belongs_to :item
has_attached_file :image,
:styles => { thumb: "100x100#", small: "400x400#", large: "700x700" }
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end
My controller looks like this:
items_controller.rb
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
# GET /items
# GET /items.json
def index
#items = Item.all
end
# GET /items/1
# GET /items/1.json
def show
end
# GET /items/new
def new
#item = Item.new
4.times {#item.item_images.build}
end
# GET /items/1/edit
def edit
4.times {#item.item_images.build}
end
# POST /items
# POST /items.json
def create
#item = Item.new(item_params)
respond_to do |format|
if #item.save
format.html { redirect_to #item, notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: #item }
else
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
respond_to do |format|
if #item.update(item_params)
format.html { redirect_to #item, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: #item }
else
format.html { render :edit }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
#item.destroy
respond_to do |format|
format.html { redirect_to items_url, notice: 'Item was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
#item = Item.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:title, :description, :price, :available, :sort_shop, :sort_gallery, :item_type, :size)
end
end
form.html.erb
<%= form_for #item, html: { multipart: true } do |f| %>
<% if #item.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#item.errors.count, "error") %> prohibited this item from being saved:</h2>
<ul>
<% #item.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :price %><br>
<%= f.text_field :price %>
</div>
<div class="field">
<%= f.label :available %><br>
<%= f.check_box :available %>
</div>
<div class="field">
<%= f.label :sort_shop %><br>
<%= f.number_field :sort_shop %>
</div>
<div class="field">
<%= f.label :sort_gallery %><br>
<%= f.number_field :sort_gallery %>
</div>
<div class="field">
<%= f.label :item_type %><br>
<%= f.text_field :item_type %>
</div>
<div class="field">
<%= f.label :size %><br>
<%= f.text_field :size %>
</div>
<%= f.fields_for :item_images do |builder| %>
<% if builder.object.new_record? %>
<div class="field">
<%= builder.label :image, "Image File" %>
<%= builder.file_field :image %>
</div>
<% end %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Try this in strong parameters in Items controller
params.require(:item).permit(:title, :description, :price, :available, :sort_shop, :sort_gallery, :item_type, :size,item_images_attributes: [:image ])
than in ItemImage.rb add this line
belongs_to :item, optional: true,
and remove this line from Item.rb
:reject_if => lambda { |t| t['item_image'].nil? }
`
If you get any error please reply

Display a nested image with paperclip and rails

I have two models :
Post and Picture
class Post < ActiveRecord::Base
has_many :picture, :dependent => :destroy
accepts_nested_attributes_for :picture, :allow_destroy => true, :reject_if => lambda { |t| t['pictures'].nil? }
end
and
class Picture < ActiveRecord::Base
belongs_to :posts
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
Picture has a paperclip attachment : image
I created a nested form but i'm not able to know if my picture is saved correctly since i can't display in the show page.
Here is my form :
<%= form_for #post, html: { multipart: true} do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :brand %><br>
<%= f.text_field :brand %>
</div>
<div class="field">
<%= f.label :model %><br>
<%= f.text_field :model %>
</div>
<div class="field"><%= f.fields_for :picture do |p| %>
<%= p.file_field :image %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My show page :
<p id="notice"><%= notice %></p>
<%= #post.picture.each do |pic| %>
<%= image_tag pic.image.url(:medium) %>
<% end %>
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<p>
<strong>Description:</strong>
<%= #post.description %>
</p>
<p>
<strong>Brand:</strong>
<%= #post.brand %>
</p>
<p>
<strong>Model:</strong>
<%= #post.model %>
</p>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Back', posts_path %>
The post controller :
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
#post.picture.build
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
if params[:image]
params[:image].each { |image|
#post.picture.create(image: image)
}
end
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :description, :brand, :model, picture_attributes: [ :id, :post_id, :image, :_destroy])
end
end
When i heat create post, i have no error the post is rendered but instead of having the image displayed i have this : "[]" ?
Terminal output :
Processing by PostsController#show as HTML
Parameters: {"id"=>"8"}
Post Load (0.4ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", 8]]
Picture Load (0.3ms) SELECT "pictures".* FROM "pictures" WHERE "pictures"."post_id" = ? [["post_id", 8]]
Is there something i did wrong ?
The first issue you have is that you've referenced your associations incorrectly:
#app/models/post.rb
class Post < ActiveRecord::Base
has_many :pictures #-> plural
end
#app/models/picture.rb
class Picture < ActiveRecord::Base
belongs_to :post #-> singular
has_attached_file :image
validates :image, content_type: { content_type: /\Aimage\/.*\Z/ }
end
You can see about the association names here:
A pro tip is to use the paperclip_defaults options in your application.rb:
#config/application.rb
...
config.paperclip_defaults: {
styles: { medium: "300x300>", thumb: "100x100>" },
default_url: "/images/:style/missing.png"
}
This will allow you to set the "defaults" for all implementations of Paperclip in your app, which can be overridden as you need in each model. Just makes it less messy I find...
In regards your error, you have all the pieces in place; I think the issue is your association names (see above).
This is what I would have:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new
#post.pictures.build #-> plural
end
def create
#post = Post.new post_params
#post.save
end
private
def post_params
params.require(:post).permit(:title, :description, :brand, :model, picture_attributes: [:image, :_destroy])
end
end
You'd then be able to use the following form:
#app/views/posts/new.html.erb
<%= form_for #post, multipart: true do |f| %>
<%= f.fields_for :pictures do |p| %>
<%= p.file_field :image %>
<% end %>
<%= f.submit %>
<% end %>
--
This should submit to your db properly; to display the images, you can use the following:
#app/views/posts/show.html.erb
<% #post.pictures.each do |picture| %>
<%= image_tag picture.image.url %>
<% end %>

I can't upload multiple image using CarrierWave and Ruby on Rails

I'm getting a trouble when I try to use a multi upload file.
this is my form partial view:
<%= simple_form_for #product, :html => { :multipart => true, :class => 'form-horizontal'} do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.input :price %>
<%= f.input :isenable, check_box_html: { class: 'check_box' } %>
<div class="row-fluid">
<ul class="thumbnails">
<%= f.simple_fields_for :attachments do |attachments_form| %>
<li class="span4">
<div class="thumbnail">
<%= image_tag attachments_form.object.image_url(:thumb).to_s if attachments_form.object %>
<%= attachments_form.label :_destroy, "Borrar Imagen" %>
<%= attachments_form.file_field :image %>
</div>
</li>
<% end %>
</ul>
</div>
<%= f.button :submit %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
products_path, :class => 'btn' %>
<% end %>
This is my controller:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/list
# GET /products/list.json
def list
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
3.times do
attachments = #product.attachments.build
end
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render action: 'show', status: :created, location: #product }
else
format.html { render action: 'new' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :description, :price, :isenable, attachments_attributes: [:image, :remove_image])
end
end
And this is the show file:
<%- model_class = Product -%>
<div class="page-header">
<h1><%=t '.title', :default => model_class.model_name.human.titleize %></h1>
</div>
<dl class="dl-horizontal">
<dt><strong><%= model_class.human_attribute_name(:name) %>:</strong></dt>
<dd class="lead"><%= #product.name %></dd>
<dt><strong><%= model_class.human_attribute_name(:description) %>:</strong></dt>
<dd class="lead"><%= #product.description %></dd>
<dt><strong><%= model_class.human_attribute_name(:price) %>:</strong></dt>
<dd class="lead"><%= #product.price %></dd>
<dt><dt>
</dl>
<div class="row-fluid">
<ul class="thumbnails">
<% #product.attachments.each do |picture| %>
<li class="span4">
<div class="thumbnail">
<%= image_tag picture.image_url(:full).to_s %>
</div>
</li>
<% end %>
</ul>
</div>
<div class="form-actions">
<%= link_to t('.back', :default => t("helpers.links.back")),
products_path, :class => 'btn' %>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_product_path(#product), :class => 'btn' %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
product_path(#product),
:method => 'delete',
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-danger' %>
</div>
I'm using Rails 4.0.0 ruby 2.0.0p247, as I said I'm using CarrierWave to upload files, in the create screen if I left the image empty it creates an empty image object. what I want is to don't create the image if the user don't add a file.
Also another problem that I have is related with the remove link. it simple doesn't work. any suggestion?
I've solved partially the problem adding the following line to my product model:
accepts_nested_attributes_for :attachments, :allow_destroy => true,
:reject_if => lambda {
|a| a['image'].blank?
}
it allows my to don't insert any image if it hasn't file. so part of my problem is already solved what I need to still solve is the fact that remove link doesn't work.
Ok reviewing the documentation of CarrierWave and principally of Rails documentation I found out the resolution of my problems. The first one as I said before the solution to prevent insert files blank was include in my products model the following line:
accepts_nested_attributes_for :attachments, :allow_destroy => true,
:reject_if => lambda {
|a| a['image'].blank?
}
To solve the problem that CarrierWave doesn't remove the images I found out that when you use nested attributes you should include the :id and :_destroy as permit in your controller like this:
# permit :id and :_destroy
params.require(:author).permit(:name, books_attributes: [:title, :id, :_destroy])
This is exactly what I did in my controller and also I've changed the name of the checkbox in the view. So in brief the controller was like this:
def product_params
params.require(:product).permit(:name, :description, :price, :isenable, attachments_attributes: [:image, :_destroy, :id])
end
and the view was in that way:
<label><%= attachments_form.check_box :_destroy %>Borrar Imagen</lable>
Doing that I finally solve both problems, thanks anyway for the help.
In your create action you have to create the attachment, you have to do something like this ..
#product.attachments.create(:attachment_id).save
where attachment_id is the id of the attachments attached with the product.

How do I access uploaded photos in in a form?

I have a form for creating a project, the project can contain five photos.
In my _form.html.erb I can't access my upladed photos when I'm calling multipart => true but in my show they are accessible. If there are any existing photos, I want to show the existing photos in the edit.erb and a delete option. I can access the uploaded photos in the show.
Here is my _form.html.erb:
<%= form_for #project, :html => { :multipart => true } do |f| %>
<% if #project.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#project.errors.count, "error") %> prohibited this project from being saved:</h2>
<ul>
<% #project.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="newPaperclipFiles">
<%= f.fields_for :assets do |asset| %>
<% if asset.object.new_record? %>
<%= asset.file_field :photo %>
<% end %>
<% end %>
</div>
<div class="existingPaperclipFiles">
<% f.fields_for :assets do |asset| %>
<% unless asset.object.new_record? %>
<div>
<%=image_tag asset.photo.url(:small) %>
</div>
<%= asset.check_box :_destroy %>
<% end %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The show.erb where I can access the photos:
<div class="existingPaperclipFiles">
<% #project.assets.each do |asset| %>
<div>
<%= image_tag asset.photo.url(:small) %>
</div>
<% end %>
</div>
<p>
<strong>Title:</strong>
<%= #project.title %>
</p>
<p>
<strong>Description:</strong>
<%= #project.description %>
</p>
<%= link_to 'Edit', edit_project_path(#project) %> |
<%= link_to 'Back', projects_path %>
My asset model:
class Asset < ActiveRecord::Base
require 'paperclip'
belongs_to :project, :foreign_key => "project_id"
attr_accessible :project_id, :photo
has_attached_file :photo, :styles => { :thumb => "600x600#", :medium => "300x300#", :small => "160x160#"}
end
My project model:
class Project < ActiveRecord::Base
has_permalink :title
default_scope :order => 'created_at desc'
attr_accessible :title, :description, :assets_attributes, :dependent => :destroy
validates_uniqueness_of :title
validates_presence_of :title
has_many :assets, :dependent => :destroy
accepts_nested_attributes_for :assets, :allow_destroy => true
end
EDIT:
Project contoller:
class ProjectsController < ApplicationController
before_filter :authenticate_admin!, :except => [:show]
before_action :set_project, only: [:show, :edit, :update, :destroy]
# GET /projects
# GET /projects.json
def index
#projects = Project.all
end
# GET /projects/1
# GET /projects/1.json
def show
end
# GET /projects/new
def new
#project = Project.new()
(5 - #project.assets.length).times { #project.assets.build }
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #project }
end
end
# GET /projects/1/edit
def edit
#project = Project.find_by_permalink(params[:id])
#assets = Project.includes(:assets).find_by_permalink(params[:id])
(5 - #project.assets.length).times { #project.assets.build }
end
# POST /projects
# POST /projects.json
def create
#project = Project.create(params[:project])
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render action: 'show', status: :created, location: #project }
else
format.html { render action: 'new' }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
#project = Project.find_by_permalink(params[:id])
respond_to do |format|
if #project.update(params[:project])
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
#project = Project.find_by_permalink(params[:id])
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find_by_permalink(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:title, :description, :assets_attributes)
end
end
Not sure if this is a typo, but try adding the = here:
<% f.fields_for :assets do |asset| %>
<%= f.fields_for :assets do |asset| %>

Nested Form (Railscast #196)

I understand some railscasts may be old, but revised shouldn't be. I am trying really hard to overcome nested form, but most answer i get is use a plugin. So i try to make the railcasts from scratch but an exception occurs. I am wondering what would be the Railcasts 196 Updated Version has today with proper code.
Here my code, maybe its a silly mistake from me.
Survey Model
class Survey < ActiveRecord::Base
has_many :questions, :dependent => :destroy
accepts_nested_attributes_for :questions , :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
attr_accessible :name, :questions_attributes
end
Question Model
class Question < ActiveRecord::Base
belongs_to :survey
attr_accessible :content, :question_id
accepts_nested_attributes_for :answers , :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
attr_accessible :name, :answers_attributes
end
Answer Model
class Answer < ActiveRecord::Base
belongs_to :questions
attr_accessible :content, :question_id
end
Survey Show Form
<p id="notice"><%= notice %></p>
<div>Name:</div>
<div><%=#survey.name%></div>
<% for question in #survey.questions %>
<div><%=h question.content%></div>
<% end %>
<%= link_to 'Edit', edit_survey_path(#survey) %> |
<%= link_to 'Back', surveys_path %>
Form.html.erb
<%= form_for(#survey) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<%= f.fields_for :questions do |bf|%>
<% render 'question_fields, :f => bf %>
<% end %>
***<div class="actions">***
<%= f.submit %>
</div>
<% end %>
question_field Form
<%= f.label :content, "Question" %><br />
<%= f.text_area :content, :rows=> 3 %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question"%><br />
<%= f.fields_for :answer do |form| %>
<%= render 'answer_fields', :f => form %>
<% end %>
answer_field Form
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove" %>
Survey Controller
class SurveysController < ApplicationController
# GET /surveys
# GET /surveys.json
def index
#surveys = Survey.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #surveys }
end
end
# GET /surveys/1
# GET /surveys/1.json
def show
#survey = Survey.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #survey }
end
end
# GET /surveys/new
# GET /surveys/new.json
def new
#survey = Survey.new
3.times {#survey.questions.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: #survey }
end
end
# GET /surveys/1/edit
def edit
#survey = Survey.find(params[:id])
end
# POST /surveys
# POST /surveys.json
def create
#survey = Survey.new(params[:survey])
respond_to do |format|
if #survey.save
format.html { redirect_to #survey, notice: 'Survey was successfully created.' }
format.json { render json: #survey, status: :created, location: #survey }
else
format.html { render action: "new" }
format.json { render json: #survey.errors, status: :unprocessable_entity }
end
end
end
# PUT /surveys/1
# PUT /surveys/1.json
def update
#survey = Survey.find(params[:id])
respond_to do |format|
if #survey.update_attributes(params[:survey])
format.html { redirect_to #survey, notice: 'Survey was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #survey.errors, status: :unprocessable_entity }
end
end
end
# DELETE /surveys/1
# DELETE /surveys/1.json
def destroy
#survey = Survey.find(params[:id])
#survey.destroy
respond_to do |format|
format.html { redirect_to surveys_url }
format.json { head :no_content }
end
end
end
Here my error when creating a new survey
Not sure what else could be wrong
ArgumentError in SurveysController#create
No association found for name `answers'. Has it been defined yet?
Here the new error
SyntaxError in Surveys#new
Showing /home/jean/rail/surveysays/app/views/surveys/_form.html.erb where line #22 raised:
/home/jean/rail/surveysays/app/views/surveys/_form.html.erb:22: syntax error, unexpected keyword_class, expecting keyword_do or '{' or '('
#output_buffer.safe_concat(' <div class="actions">
^
/home/jean/rail/surveysays/app/views/surveys/_form.html.erb:24: unterminated regexp meets end of file
/home/jean/rail/surveysays/app/views/surveys/_form.html.erb:24: syntax error, unexpected $end, expecting keyword_end
Add has_many :answers to the Question model and change the Answer model to belongs_to :question.

Resources