formal argument cannot be an instance variable? - ruby-on-rails

<% #idea.each do |#idea| %>
<div id="basic_details" class="idea-show-columns">
<%= render :partial => '/ideas/idea_basic_show', :locals => {:idea => #idea} %>
<%= render :partial => 'ideas/comments' %>
<%= render :partial => 'ideas/mockups' %>
</div>
<div id="copy_details" class="idea-show-columns">
<%= render :partial => 'ideas/ copy_show', :locals => {:idea => #idea} %>
</div>
<% end %>
When I take the # off it says "Parameter 'idea' is not used", I cannot find the proper syntax for this.
IdeasController
class IdeasController < ApplicationController
def index
respond_to do |format|
if request.xhr?
#ideas = Idea.select("sku, id").order(:sku)
else
if params[:search]
#ideas = Idea.where("sku like '%#{params[:search]}%' or working_name like '%#
{params[:search]}%' or product_name like '%#{params[:search]}%'").paginate(:page =>
params[:page]).reload
else
#ideas = Idea.paginate(:page => params[:page]).reload
end
end
format.html
format.json {render json: #ideas.where("sku like ?", "%#{params[:q]}%") }
end
end
def show
#idea = Idea.find_by_permalink(params[:id])
end
def new
#idea = Idea.new
end
def create
#idea = Idea.new(new_idea_params)
if #idea.save
flash[:notice] = 'Idea created!'
redirect_to ideas_url
else
render :new
end
end
def edit
#idea = Idea.find_by_permalink(params[:id])
end
def update
#idea = Idea.find_by_permalink(params[:id])
if request.xhr?
if params[:comment]
#idea.comments.create(:title => params[:comment][:title], :comment => params[:comment][:comment], :user_id => current_user.id)
end
if #idea.update_attributes(update_status_params)
#success = true
else
#success = false
end
else
if #idea.update_attributes(edit_idea_params)
flash[:notice] = 'Idea updated!'
redirect_to idea_url(params[:id])
else
render :edit
end
end
end
def destroy
Idea.find_by_permalink(params[:id]).destroy
flash[:success] = "Idea destroyed."
redirect_to ideas_url
end
def generate_mockups
idea = Idea.find_by_permalink(params[:id])
begin
idea.generate_mockups
rescue Exception => e
flash[:error] = "There was an error generating the mockups for #{idea.working_name}! # {e.message}"
end
flash[:notice] = "Successfully generated mockups for #{idea.working_name}"
redirect_to idea_url(params[:id])
end
def signoff
if current_user.has_overlord_access?
if params[:idea_id]
idea = Idea.find(params[:idea_id])
idea.overlord_id = current_user.id
idea.status = 'Ready To Publish'
idea.save
flash[:notice] = "#{current_user.full_name} just signed off on #{idea.sku}"
redirect_to :action => :signoff
end
#ideas = Idea.awaiting_overlord_signoff.reload
#idea = #ideas.first.reload
else
flash[:notice] = 'Sorry, you must have overlord access to sign off on ideas.'
redirect_to ideas_path
end
end
private
def new_idea_params
params.require(:idea).permit(:sku, :working_name, :working_description, :priority)
end
def update_status_params
params.require(:idea).permit(:art_status, :copy_status)
end
def edit_idea_params
(params[:idea][:color_ids] ||= []) unless !current_user.has_artist_access?
(params[:idea][:imprintable_ids] ||= []) unless !current_user.has_copywriter_access?
(params[:idea][:stores_ids] ||= []) unless !current_user.has_copywriter_access?
(params[:idea][:taxonomies_ids] ||= []) unless !current_user.has_copywriter_access?
params.require(:idea).permit(:sku, :working_name, :working_description, :priority,
:product_name, :product_line_tokens,
:description, :meta_description, :meta_keywords, :artist_id,
:copywriter_id, :overlord_id,
{:store_ids => []}, {:taxonomy_ids => []}, :base_price,
:shipping_category, :default_artwork_id,
:tax_category, {:imprintable_ids => []}, :marketplace,
:product_type,
:base, :colors_offered, :special_instructions, :copy_status,
:art_status, {:color_ids => []},
:artworks_attributes => [:height, :width, :from_top,
:from_center, :idea_id, :dimensions, :file, :_destroy, :id])
end
def update_status_params
params.require(:idea).permit(:copy_status, :art_status)
end
end
I am getting the error
undefined method `each' for nil:NilClass

It should :
<% unless #ideas.nil? %>
<% #ideas.each do |idea| %>
<div id="basic_details" class="idea-show-columns">
<%= render :partial => '/ideas/idea_basic_show', :locals => {:idea => idea} %>
<%= render :partial => 'ideas/comments' %>
<%= render :partial => 'ideas/mockups' %>
</div>
<div id="copy_details" class="idea-show-columns">
<%= render :partial => 'ideas/ copy_show', :locals => {:idea => idea} %>
</div>
<% end %>
<% end %>

Few things:
if you need to use #ideas in show view you need to load them using before_filter
dont do this dea.where("sku like '%#{params[:search]}%' because this is not secure. Do something like where("code = ?", params[:code])

Related

NoMethodError in Refinery::Blog::Posts#index

When I want to go to "localhost:3000/blog" the web page gives this error...
Showing C:/Sites/ifurniture/app/views/refinery/blog/posts/index.html.erb where line #3 raised:
undefined method `to_sym' for {:title=>"Body", :slug=>"body"}:Hash
Rails.root: C:/Sites/ifurniture
this is the blog controller..
module Refinery
module Blog
class PostsController < BlogController
before_filter :find_all_blog_posts, :except => [:archive]
before_filter :find_blog_post, :only => [:show, :comment, :update_nav]
before_filter :find_tags
respond_to :html, :js, :rss
def index
if request.format.rss?
#posts = if params["max_results"].present?
# limit rss feed for services (like feedburner) who have max size
Post.recent(params["max_results"])
else
Post.newest_first.live.includes(:comments, :categories)
end
end
respond_with (#posts) do |format|
format.html
format.rss { render :layout => false }
end
end
def show
#comment = Comment.new
#canonical = refinery.url_for(:locale => Refinery::I18n.current_frontend_locale) if canonical?
#post.increment!(:access_count, 1)
respond_with (#post) do |format|
format.html { present(#post) }
format.js { render :partial => 'post', :layout => false }
end
end
def comment
#comment = #post.comments.create(comment_params)
if #comment.valid?
if Comment::Moderation.enabled? or #comment.ham?
begin
CommentMailer.notification(#comment, request).deliver_now
rescue
logger.warn "There was an error delivering a blog comment notification.\n#{$!}\n"
end
end
if Comment::Moderation.enabled?
flash[:notice] = t('thank_you_moderated', :scope => 'refinery.blog.posts.comments')
redirect_to refinery.blog_post_url(params[:id])
else
flash[:notice] = t('thank_you', :scope => 'refinery.blog.posts.comments')
redirect_to refinery.blog_post_url(params[:id],
:anchor => "comment-#{#comment.to_param}")
end
else
render :show
end
end
def archive
if params[:month].present?
date = "#{params[:month]}/#{params[:year]}"
archive_date = Time.parse(date)
#date_title = ::I18n.l(archive_date, :format => '%B %Y')
#posts = Post.live.by_month(archive_date).page(params[:page])
else
date = "01/#{params[:year]}"
archive_date = Time.parse(date)
#date_title = ::I18n.l(archive_date, :format => '%Y')
#posts = Post.live.by_year(archive_date).page(params[:page])
end
respond_with (#posts)
end
def tagged
#tag = ActsAsTaggableOn::Tag.find(params[:tag_id])
#tag_name = #tag.name
#posts = Post.live.tagged_with(#tag_name).page(params[:page])
end
private
def comment_params
params.require(:comment).permit(:name, :email, :message)
end
protected
def canonical?
Refinery::I18n.default_frontend_locale != Refinery::I18n.current_frontend_locale
end
end
end
end
the post controller...
module Refinery
module Blog
class PostsController < BlogController
before_filter :find_all_blog_posts, :except => [:archive]
before_filter :find_blog_post, :only => [:show, :comment, :update_nav]
before_filter :find_tags
respond_to :html, :js, :rss
def index
if request.format.rss?
#posts = if params["max_results"].present?
# limit rss feed for services (like feedburner) who have max size
Post.recent(params["max_results"])
else
Post.newest_first.live.includes(:comments, :categories)
end
end
respond_with (#posts) do |format|
format.html
format.rss { render :layout => false }
end
end
def show
#comment = Comment.new
#canonical = refinery.url_for(:locale => Refinery::I18n.current_frontend_locale) if canonical?
#post.increment!(:access_count, 1)
respond_with (#post) do |format|
format.html { present(#post) }
format.js { render :partial => 'post', :layout => false }
end
end
def comment
#comment = #post.comments.create(comment_params)
if #comment.valid?
if Comment::Moderation.enabled? or #comment.ham?
begin
CommentMailer.notification(#comment, request).deliver_now
rescue
logger.warn "There was an error delivering a blog comment notification.\n#{$!}\n"
end
end
if Comment::Moderation.enabled?
flash[:notice] = t('thank_you_moderated', :scope => 'refinery.blog.posts.comments')
redirect_to refinery.blog_post_url(params[:id])
else
flash[:notice] = t('thank_you', :scope => 'refinery.blog.posts.comments')
redirect_to refinery.blog_post_url(params[:id],
:anchor => "comment-#{#comment.to_param}")
end
else
render :show
end
end
def archive
if params[:month].present?
date = "#{params[:month]}/#{params[:year]}"
archive_date = Time.parse(date)
#date_title = ::I18n.l(archive_date, :format => '%B %Y')
#posts = Post.live.by_month(archive_date).page(params[:page])
else
date = "01/#{params[:year]}"
archive_date = Time.parse(date)
#date_title = ::I18n.l(archive_date, :format => '%Y')
#posts = Post.live.by_year(archive_date).page(params[:page])
end
respond_with (#posts)
end
def tagged
#tag = ActsAsTaggableOn::Tag.find(params[:tag_id])
#tag_name = #tag.name
#posts = Post.live.tagged_with(#tag_name).page(params[:page])
end
private
def comment_params
params.require(:comment).permit(:name, :email, :message)
end
protected
def canonical?
Refinery::I18n.default_frontend_locale != Refinery::I18n.current_frontend_locale
end
end
end
end
and this is the index.html.erb of Blog.
<section class="container">
<% content_for :body do %>
<%= raw #page.content_for(Refinery::Pages.default_parts.first.to_sym) if Refinery::Pages.default_parts.any? %>
<% if #posts.any? %>
<section id="blog_posts" class="news">
<%= render :partial => "/refinery/blog/shared/post", :collection => #posts %>
<%= will_paginate #posts %>
</section>
<% else %>
<p><%= t('.no_blog_articles_yet') %></p>
<% end %>
<% end %>
<% content_for :side_body_prepend do -%>
<%= raw #page.content_for(Refinery::Pages.default_parts.second.to_sym) %>
<% end if Refinery::Pages.default_parts.many? -%>
<%= render "/refinery/content_page" %>
<% content_for :stylesheets, stylesheet_link_tag('refinery/blog/frontend') %>
</section>
I'll be watching for your help, thanks.
You can use to_sym method on hash or string so in your code you can do something like this:
index.html
instead this:
<%= raw #page.content_for(Refinery::Pages.default_parts.first.to_sym) if Refinery::Pages.default_parts.any? %>
put this:
<%= raw #page.content_for(Refinery::Pages.default_parts.first[:title].to_sym) if Refinery::Pages.default_parts.any? %>
instead [:title]you can also use [:slug]

Albums in rails

I would like to create an image gallery in rails. I have produced a setup that allows you to create an album and upload photos to it. However, I am stumped on how I could allow the user to set one of the existing images as the album cover in the image's index view.
Anyone have some ideas? I found that if I used radio buttons, I couldn't figure hout how to determine which image was selected by ajax. I also don't know how I would force only one image being set as album cover.
Here is my setup:
Controller
class Admin::AlbumsController < ApplicationController
respond_to :html, :json
def index
#albums = Album.all
end
def new
#album = Album.new
end
def create
#album = Album.new(params[:album])
if #album.save
flash[:notice] = "Successfully created album!"
redirect_to [:admin, :albums]
else
render "new"
end
end
def edit
#album = Album.find(params[:id])
end
def show
#album = Album.find(params[:id])
end
def update
#album = Album.find(params[:id])
#album.update_attributes(params[:album])
if #album.update_attributes(params[:album])
respond_with #album
flash[:notice] = "Successfully updated Album"
else
render "edit"
end
end
def destroy
#album = Album.find(params[:id])
#album.destroy
#id = #album.id
FileUtils.remove_dir("#{Rails.root}/public/uploads/image/picture/#{#id}", :force => true)
respond_to do |format|
format.js { render :layout => false }
end
redirect_to admin_albums_path
end
def random_image
#image_files = %w( .jpg .gif .png )
#files ||= Dir.entries(
"#{RAILS_ROOT}/public/uploads").delete_if { |x|
!#image_files.index(x[-4,4])
}
file = #files[rand(#files.length)];
#files.delete file
return "/images/logos/#{file}"
end
def ajaxUpdate
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:albumcover])
if #image.update_attributes(params[:image])
flash[:notice] = "Successfully updated Image"
else
render "edit"
end
end
end
class Admin::ImagesController < ApplicationController
respond_to :html, :json
#before_filter :split_hash, :only => [ :create, :update ]
def index
#album = Album.find(params[:album_id])
#images = #album.images.all
end
def new
#album = Album.find(params[:album_id])
#image = #album.images.new
end
def create
params[:image][:source].each do |image|
#album = Album.find(params[:album_id])
#params = {}
#params['source'] = image
#image = #album.images.create(#params)
end
if #image.save
if params[:image][:source].size > 1
flash[:notice] = "Successfully added images!"
else
flash[:notice] = "Successfully added image!"
end
redirect_to [:admin, #album, :images]
else
render "new"
flash[:notice] = "Did not successfully add image :("
end
end
def show
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:id])
end
def edit
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:id])
end
def update
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:id])
if #image.update_attributes(params[:image])
redirect_to [:admin, #album, :images]
flash[:notice] = "Successfully updated Image"
else
render "edit"
end
end
def destroy
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:id])
#image.destroy
#albumid = #album.id
#id = #image.id
FileUtils.remove_dir("#{Rails.root}/public/uploads/image/picture/#{#albumid}/#{#id}", :force => true)
redirect_to admin_album_images_path(#album)
end
def ajaxUpdate
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:albumcover])
if #image.update_attributes(params[:image])
flash[:notice] = "Successfully updated Image"
else
render "edit"
end
end
# def split_hash
# #album = Album.find(params[:album_id])
# #image = #album.images
# array_of_pictures = params[:image][:picture]
# array_of_pictures.each do |pic|
# size = array_of_pictures.size.to_i
# size.times {#image.build(params[:image], :picture => pic)}
# #image.save
# end
# end
end
Models
class Album < ActiveRecord::Base
attr_accessible :title, :description, :album_id
has_many :images, :dependent => :destroy
validates :title, :description, :presence => true
end
class Image < ActiveRecord::Base
attr_accessible :title, :description, :source, :album_id, :albumcover, :image, :image_id
belongs_to :album
accepts_nested_attributes_for :album
mount_uploader :source, PictureUploader
end
View
<% content_for :head do %>
<%= stylesheet_link_tag 'admin/images' %>
<%= javascript_include_tag "admin.js" %>
<% end %>
<% content_for :menu do %>
<li class="menu_item"><%=link_to "New Album", :controller => "albums", :action => "new" %></li>
<li class="menu_item"><%= link_to "Add Images", {:controller => "images", :action => "new"}, :class => "highlight_menu"%> </li>
<% end %>
<%= link_to "< Back", admin_albums_path, :id => "return_link" %> </br>
<h1 class="section-title"> <strong style="font-weight: 600;"><%=best_in_place [:admin,#album], :title, :ok_button => :confirm %></strong></h1>
<h4 class="album-desc"><%= best_in_place [:admin,#album], :description, :type => :textarea, :ok_button => :confirm%></h4>
<%= form_tag admin_album_images_path(#album) do %>
<% if !#images.blank? %>
<% #images.each do |image| %>
<div class="item">
<div class="image-box">
<div class="source">
<%= image_tag image.source %>
</div>
</div>
<div class="info">
<div class="item-links">
<%= link_to "Edit", edit_admin_album_image_path(#album, image.id), :id => "edit"%>
<%= link_to "Delete",
admin_album_image_path(#album, image.id),
:class => "item-link delete-image",
:method => :delete,
:remote => true,
:confirm => "Are you sure?" %>
</div>
</div>
</div>
<% end %>
<% else %>
<p class="alert">No images in this album</p>
<% end %>
<% end %>
Answer!
*albums_controller*
def albumCoverSet
#album = Album.find(params[:album_id])
#image = #album.images.find(params[:albumcover])
if #image.update_attributes(params[:image])
flash[:notice] = "Successfully updated Image"
else
render "edit"
end
end
* album view *
<div class="image">
<%= image_tag album.images.find(album.albumcover_id).source, :class => "image" %>
</div>
model
class Album < ActiveRecord::Base
attr_accessible :title, :description, :album_id, :albumcover_id
has_many :images, :dependent => :destroy
has_one :albumcover, :class_name => "Image"
validates :title, :description, :presence => true
end
You can add a 'primary_image_id' to the Album in a migration.
has_one :primary_image, :class_name => 'Image'
In your form, you can show all album.images and select one. Radio buttons should work just fine.
Submitting the value of the param would set the primary_image_id.

Ruby on Rails: If error flags, page does not hold data entered by user

I have an app that allows users to enter a project into a database.
They get the option to either enter new data via a textbox for some field, or can select data via a drop down menu, that has been entered before for that field.
If the user fills out the form, then clicks submit, but there is a problem, like they have missed out one of the fields, the page flags up an error saying which fields are missing, which is fine.
However, if the user had entered new data in the text boxes, that gets deleted, and the first option in the drop down is selected instead.
Here is my project controller:
class ProjectsController < ApplicationController
before_filter :authenticate_user!
#:except => [:show, :index]
def index
#projects = Project.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #projects }
end
end
# GET /projects/1
# GET /projects/1.json
def show
#project = Project.find(params[:id])
#project_project_id = params[:id]
respond_to do |format|
format.html # show.html.erb
format.json { render json: #project }
end
end
# GET /projects/new
# GET /projects/new.json
def new
#project = Project.new
#technol = Technol.new(params[:tech])
#all_technols = Technol.all
tech_ids = params[:technols][:id].reject(&:blank?) unless params[:technols].nil?
#project_technol = #project.projecttechnols.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #project }
end
end
# GET /projects/1/edit
def edit
#project = Project.find(params[:id])
#project_technol = #project.projecttechnols.build
puts #project.inspect
puts #project.technols.inspect
end
# POST /projects
# POST /projects.json
def create
#project = Project.new(params[:project])
#project.client = params[:new_client] unless params[:new_client].blank?
#project.role = params[:new_role] unless params[:new_role].blank?
#project.industry = params[:new_industry] unless params[:new_industry].blank?
#project.business_div = params[:new_business_div] unless params[:new_business_div].blank?
if !params[:technols].nil?
params[:technols][:id].each do |tech|
if !tech.empty?
#project_technol = #project.projecttechnols.build(:technol_id => tech)
end
end
end
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render json: #project, status: :created, location: #project }
else
format.html { render action: "new" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# PUT /projects/1
# PUT /projects/1.json
# PUT /projects/1
# PUT /projects/1.json
def update
#project = Project.find(params[:id])
puts #project.inspect
puts #project.technols.inspect
#project.client = params[:new_client] unless params[:new_client].blank?
#project.role = params[:new_role] unless params[:new_role].blank?
#project.industry = params[:new_industry] unless params[:new_industry].blank?
#project.business_div = params[:new_business_div] unless params[:new_business_div].blank?
respond_to do |format|
if #project.update_attributes(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(params[:id])
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url }
format.json { head :no_content }
end
end
private
helper_method :sort_column, :sort_direction
def sort_column
Project.column_names.include?(params[:sort]) ? params[:sort] : "project_name"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
def per_page
params[:per_page] ||= 1
end
def page
params[:page] ||= 1
end
end
Here is some of my new project view
<%= stylesheet_link_tag "new" %>
<h1>Create New Project</h1>
<HTML>
<%= stylesheet_link_tag "form" %>
<%= form_for(#project) 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 %>
<CENTER>
<div id = "project_name">
<div class="project_name">
Project Name:
<%= f.text_field :project_name,:maxlength => 30 %>
</div>
</div>
<div id ="smallbox">
<div id = "status">
<div class="status">
<%= f.label :status %> :
<%#= f.select :status, [['Active'],['Completed']], {:include_blank => true} %>
<%= f.select :status, [['Active'],['Completed']] %>
</div></div>
<div class="client" STYLE="text-align: left;">
<%= label_tag :new_client, "Client" %><br/>
<%= text_field_tag :new_client, nil, :maxlength => 30 %>
Or
<%= f.select( :client, Project.all.map {|p| [p.client]}.uniq, :prompt => "Select previous..") %>
</div>
<div class="business_div" STYLE="text-align: left;">
<%= label_tag :new_business_div, "Business Division" %><br/>
<%= text_field_tag :new_business_div, nil, :maxlength => 30 %>
Or
<%= f.select( :business_div, Project.all.map {|p| [p.business_div]}.uniq, :prompt => "Select previous") %>
</div>
<div class="start_date" STYLE="text-align: left;">
<b>Start Date:</b>
<%= f.text_field :start_date, :class => 'datepicker', :style => 'width: 80px;' %>
</div>
</P>
<div class="create_button">
<div class="actions">
<%= f.submit "Save New Project", :class => "button", :confirm => "Are you sure you want to save the new project?" %>
</div>
</div>
</div> <%#= small div %>
<% end %>
<div class="back_button2">
<%= button_to "Back", projects_path , :class => "button", :method => "get" %>
</div>
Here is my project model
class Project < ActiveRecord::Base
attr_accessible :fullname, :edited_first_name, :edited_last_name, :first_name, :last_name, :business_div, :client, :customer_benefits, :edited_date, :end_date, :entry_date, :financials, :industry, :keywords, :lessons_learned, :project_name, :role, :start_date, :status, :summary, :technol_ids, :tech , :technols
validates_presence_of :business_div, :client, :customer_benefits, :end_date, :financials, :industry, :lessons_learned, :project_name, :role, :start_date, :status, :summary #, :keywords
validates_format_of :industry, :with => /\A[^\d]+\Z/, :message => "field should only have letters"
validates_format_of :business_div, :with => /\A[^\d]+\Z/, :message => "field should only have letters"
validates_format_of :client, :with => /\A[^\d]+\Z/, :message => "field should only have letters"
validates_format_of :exception_pm, :with => /\A[^\d]+\Z/, :message => "field should only have letters"
validates_format_of :project_owner, :with => /\A[^\d]+\Z/, :message => "field should only have letters"
validates_format_of :role, :with => /\A[^\d]+\Z/, :message => "field should only have letters"
has_many :projecttechnols
has_many :technols, :through => :projecttechnols
def set_fullname(a, b)
fullname = [a, b].join(' ')
end
accepts_nested_attributes_for(:technols)
end
If I need to include anything else please let me know. I have been stuck with this problem for some time now. Thank you in advance.
As railsdog suggests, use the data passed to Projects#create. Your form submits data and that data is held in a variable called params as key/value pairs. That variable should still be accessible from whichever view Projects#create renders.
What you need to do is to set some default content on your form elements. Here's an example for the text_field called "project_name"
<div class="project_name">
Project Name:
<%= f.text_field :project_name, params[:project_name],:maxlength => 30 %>
</div>
You should be able to do the same or something similar with any other fields.

rails: "unknown action" message when action is clearly specified

I had hard time to figure out why I've been getting "unknown action" error message when I was do some editing:
Unknown action
No action responded to 11. Actions: bin, create, destroy, edit, index, new, observe_new, show, tag, update, and vote
you can see that Rails did mention each action in the above list - update. And in my form, I did specify action = "update".
I wonder if some friends could kindly help me with the missing links...
here is the code:
edit.rhtml
<h1>Editing tip</h1>
<% form_tag :action => 'update', :id => #tip do %>
<%= render :partial => 'form' %>
<p>
<%= submit_tag_or_cancel 'Save Changes' %>
</p>
<% end %>
_form.rhtml
<%= error_messages_for :tip %>
<p><label>Title<br/>
<%= text_field :tip, :title %></label></p>
<p><label>Categories<br/>
<%= select_tag('categories[]', options_for_select(Category.find(:all).collect {|c| [c.name, c.id] }, #tip.category_ids), :multiple => true ) %></label></p>
<p><label>Abstract:<br/>
<%= text_field_with_auto_complete :tip, :abstract %></label></p>
<p><label>Name: <br/>
<%= text_field :tip, :name %></label></p>
<p><label>Link: <br/>
<%= text_field :tip, :link %></label></p>
<p><label>Content<br/>
<%= text_area :tip, :content, :rows => 5 %></label></p>
<p><label>Tags <span>(space separated)</span><br/>
<%= text_field_tag 'tags', #tip.tag_list, :size => 40 %></label></p>
class TipsController < ApplicationController
before_filter :authenticate, :except => %w(index show)
# GET /tips
# GET /tips.xml
def index
#tips = Tip.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #tips }
end
end
# GET /tips/1
# GET /tips/1.xml
def show
#tip = Tip.find_by_permalink(params[:permalink])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #tip }
end
end
# GET /tips/new
# GET /tips/new.xml
def new
#tip = session[:tip_draft] || current_user.tips.build
end
def create
#tip = current_user.tips.build(params[:tip])
#tipMail=params[:email]
#if tipMail
# TipMailer.deliver_email_friend(params[:email], params[:name], tip)
# flash[:notice] = 'Your friend has been notified about this tip'
#end
#tip = current_user.tips.build(params[:tip])
#tip.categories << Category.find(params[:categories]) unless params[:categories].blank?
#tip.tag_with(params[:tags]) if params[:tags]
if #tip.save
flash[:notice] = 'Tip was successfully created.'
session[:tip_draft] = nil
redirect_to :action => 'index'
else
render :action => 'new'
end
end
def edit
#tip = Tip.find(params[:id])
end
def update
#tip = Tip.find(params[:id])
respond_to do |format|
if #tip.update_attributes(params[:tip])
flash[:notice] = 'Tip was successfully updated.'
format.html { redirect_to(#tip) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #tip.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#tip = Tip.find(params[:id])
#tip.destroy
respond_to do |format|
format.html { redirect_to(tips_url) }
format.xml { head :ok }
end
end
def observe_new
session[:tip_draft] = current_user.tips.build(params[:tip])
render :nothing => true
end
end
the quick answer is that form_tag doesn't support :action as an option, you want to be passing a string as a path in. A slightly longer answer is you shouldn't be using form_tag anyways for a model edit form, you should be using form_for.
what rails are you using? .rhtml is pretty old, rails generators should be giving you .html.erb files. if it is something even remotely recent, you should be able to use
<% form_for #tip do |f| %>
<%= f.label :title, 'Title' %><br />
<%= f.text_field %>
... etc
<% end %>

Confused as to which Prototype helper to use (updated)

This is a continuation of Confused as to which Prototype helper to use. My code has been updated to reflect other user's suggestions:
(model) message.rb:
class Message < ActiveRecord::Base
after_create :destroy_old_messages
def old_messages
messages = Message.all(:order => 'updated_at DESC')
if messages.size >= 24
return messages[24..-1]
else
return []
end
end
protected # works without protected
def destroy_old_messages
messages = Message.all(:order => 'updated_at DESC')
messages[24..-1].each {|p| p.destroy } if messages.size >= 24
end
end
(view) index.html.erb:
<div id="messages">
<%= render :partial => #messages %>
</div>
<%= render :partial => "message_form" %>
(view) _message.html.erb:
<% div_for message do %>
<%= h message.created_at.strftime("%X") %> - <%= h message.author %><%= h message.message %>
<% end %>
(view) _message_form.html.erb:
<% remote_form_for :message, :url => { :action => "create" }, :html => { :id => 'message_form'} do |f| %>
<%= f.text_area :message, :size => "44x3" %><br />
<%= submit_to_remote 'submit_btn', 'submit', :url => { :action => 'create' } %><br />
<% end %>
(view) create.rjs:
page.insert_html :top, :messages, :partial => #message
page[#message].visual_effect :grow
page[:message_form].reset
flash[:notice]
flash.discard
# #old_messages.each do |m|
# page.remove(m.id)
# end
(controller) messages_controller.rb:
class MessagesController < ApplicationController
def index
#messages = Message.all(:order => "created_at DESC")
respond_to do |format|
format.html
format.js
end
end
def new
#message = Message.new
respond_to do |format|
format.html
end
end
def create
#message = Message.new(params[:message])
# #old_messages = Message.old_messages
respond_to do |format|
if #message.save
flash[:notice] = 'message created.'
format.html { redirect_to(messages_url) }
format.js
else
format.html { render :action => "new" }
end
end
end
def update
#message = Message.find(params[:id])
respond_to do |format|
if #message.update_attributes(params[:message])
flash[:notice] = 'message updated.'
format.html { redirect_to(messages_url) }
format.js
else
format.html { render :action => "edit" }
end
end
end
def destroy
#message = Message.find(params[:id])
#message.destroy
respond_to do |format|
format.html { redirect_to(messages_url) }
format.js
end
end
end
With the exception of the old_messages method in the model, all of the commented code were recommended changes from the previous post to make this work. But as soon as I uncomment the last three lines from create.rjs and #old_messages = Message.old_messages from the controller, I can't even submit messages with the message_form partial. Can anyone see what's wrong here? I'm just trying to create a basic app to help further my understanding of rails and rjs. I would greatly appreciate any suggestions or corrections you have to share, thank you for reading my post.
it's not what you're asking for, but i have a suggestion...
to get the older messages you can use named_scope.
in your case, (if i understood what you want) i think it would be something like:
# model
named_scope :limit, lambda { |num| { :limit => num } }
named_scope :order, lambda { |ord| { :order => ord } }
and
#controller
Message.order("updated_at DESC").limit(24)
the problem is that old_messages is an instance method, and you're calling from a class.
if you do
def self.old_messages
# ...
end
it's now a class method.
this blog has a good explanation about class and instance methods.

Resources