I'm new to rails and am having challenges adding a commenting system to my listings model. Effectively I have listings that are created by users, and I want the ability to allow other users to make comments on these listings.
What I have so far:
A listing model that includes:
has_many :comments
a comment model that includes:
belongs_to :listing
a comments controller:
class CommentsController < ApplicationController
def create
#listing = Listing.find(params[:listing_id])
#comment = #listing.comments.build(params[:body]) # ***I suspected that I needed to pass :comment as the params, but this throws an error. I can only get it to pass with :body ***
respond_to do |format|
if #comment.save
format.html { redirect_to #listing, notice: "Comment was successfully created" }
format.json { render json: #listing, status: :created, location: #comment }
else
format.html { render action: "new" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
end
def comment_params
params.require(:comment).permit(:body, :listing_id)
end
and finally a listing view that includes the following code to collect and display comments:
<div class="form-group">
<%= form_for [#listing, Comment.new] do |f| %>
<%= f.label :comments %>
<%= f.text_area :body, :placeholder => "Tell us what you think", class: "form-control", :rows => "3" %>
<p><%= f.submit "Add comment", class: "btn btn-primary" %></p>
<% end %>
</div>
<%= simple_form_for [#listing, Comment.new] do |f| %>
<p>
<%= f.input :body, :label => "New comment", as: :text, input_html: { rows: "3" } %>
</p>
<p><%= f.submit "Add comment", class: "btn btn-primary" %></p>
<% end %>
The comment box is displaying correctly in the view, and I'm able to submit comments, however it appears that the :body isn't being saved, and therefore the "submitted x minutes ago" is the only thing that's showing up in my comments section.
Any ideas on what I could be doing incorrectly? I suspect it's a params issue, but haven't been able to work it out.
Thanks!
Since you are using the strong_parameters paradigm in Rails 4, I think you should change the comment creation line to this:
#comment = #listing.comments.build(comment_params)
And I'd change the listing finding line to this:
#listing = Listing.find(params.permit(:listing_id))
It should work fine, as long as you correctly whitelist all required params in the comment_params method.
Related
I got an issue with uploading multiple files to AWS. I have two models Lessons && Attachments. Lessons has_many :attachments and I'm setting up a form that has lesson fields and I want to upload multiple attachments to that lesson. Everything uploads correctly except when I upload multiple files, it creates a new lesson and attachment. I'm working off:
https://gorails.com/episodes/multiple-file-uploads-with-shrine?autoplay=1
And
https://u.osu.edu/hasnan.1/2014/03/30/rails-4-multiple-file-upload-with-carrierwave-nested-form-and-jquery-file-upload/
Models
Lessons Model
class Lesson < ApplicationRecord
belongs_to :user
has_many :attachments, dependent: :destroy
accepts_nested_attributes_for :attachments
end
Attachment Model
class Attachment < ApplicationRecord
belongs_to :lesson, optional: true
include AttachmentUploader::Attachment.new(:media)
end
Controllers
Lessons controller
Class LessonsController < ApplicationController
# truncated for brevity.
def new
#lesson = current_user.lessons.build
end
def create
#lesson = current_user.lessons.build(lesson_params)
respond_to do |format|
if #lesson.save
if params[:media]
params[:media].each { |media|
#lesson.attachments.create(media_data: media)
}
end
format.html { redirect_to #lesson, notice: 'Lesson was successfully created.' }
format.json { render :show, status: :created, location: #lesson }
else
puts "\n\n\n#{#lesson.errors.full_messages.to_sentence}\n\n\n"
format.html { render :new, notice: #lesson.errors }
end
end
end
private
def set_lesson
#lesson = Lesson.find(params[:id])
end
def lesson_params
params.require(:lesson).permit(
:title,
:content,
:document,
:category_id,
:pinned,
:bootsy_image_gallery_id,
attachments_attributes: {media: []},
)
end
end
Attachment Controller
class AttachmentsController < ApplicationController
before_action :set_attachment, only: [:edit, :update, :destroy]
def create
#attachment = Attachment.new(attachment_params)
#attachment.save
end
private
def set_attachment
#attachment = Attachment.find(params[:id])
end
def attachment_params
params.fetch(:attachment, {})
end
end
ERB
_form.html.erb
<%= #lesson.errors.full_messages.first if #lesson.errors.any? %>
<%= form_for #lesson do |f| %>
<div class="control-group">
<%= f.label :title %>
<div class="controls">
<%= f.text_field :title, required: true %>
</div>
<div>
<%= f.label :content %>
<%= f.bootsy_area :content, editor_options: { html: false }, rows: "20", cols: "100" %>
</div>
<div>
<%= f.label 'File under at least one class' %>
<%= f.collection_select :category_id, Subject.all, :id, :name, { promt: "Choose a Class" } %>
</div>
<div>
<%= f.label :pinned %>
<%= f.label :pinned, "Yes", value: "Yes" %>
<%= f.radio_button :pinned, true%>
<%= f.label :pinned, "No", value: "No" %>
<%= f.radio_button :pinned, false, checked: true %>
</div>
<hr>
<div>
<%= f.label 'Or Upoad a file' %>
<%
######################
# This is where I have the attachment file field.
######################
%>
<%= file_field_tag "media[]", type: :file, multiple: true %>
</div>
<br>
<%= f.submit nil %>
<%= link_to 'Cancel', lessons_path%>
<div class="form-actions btn-a">
<%= link_to 'Cancel', lessons_path, class: "btn btn-default" %>
</div>
Routes
Rails.application.routes.draw do
mount AttachmentUploader::UploadEndpoint => "/attachments/upload"
resources :lessons do
member do
put "like", to: "lessons#upvote"
put "dislike", to: "lessons#downvote"
end
resources :comments
resources :attachments
end
root 'static#index'
end
JS
$(document).on("turbolinks:load", function () {
$("[type=file]").fileupload({
add: function (e, data) {
data.progressBar = $('<div class="progress" style="width: 300px"><div class="progress-bar"></div></dov>').insertAfter("#file-upload");
var options = {
extension: data.files[0].name.match(/(\.\w+)?$/)[0],
_: Date.now() // revent caching
}
$.getJSON("/attachments/upload/cache/presign", options, function (result) {
data.formData = result['fields'];
data.url = result['url'];
data.paramName = "file";
data.submit();
});
},
progress: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
var percentage = progress.toString() + '%';
data.progressBar.find(".progress-bar").css("width", percentage).html(percentage);
},
done: function (e, data) {
console.log("done", data);
data.progressBar.remove();
var document = {
id: data.formData.key.match(/cache\/(.+)/)[1],
storage: 'cache',
metadata: {
size: data.files[0].size,
filename: data.files[0].name.match(/[^\/\\]+$/)[0],
mime_type: data.files[0].type
}
}
form = $(this).closest("form");
form_data = new FormData(form[0]);
form_data.append($(this).attr("name"), JSON.stringify(document))
$.ajax(form.attr("action"), {
contentType: false,
processData: false,
data: form_data,
method: form.attr("method"),
dataType: "json",
success: function(response) {
var $img = $("<img/>", { src: response.image_url, width: 400 });
var $div = $("<div/>").append($img);
$("#photos").append($div);
}
});
}
});
});
The reason this is happening is because the Javascript looks for the URL of the file field's parent form. You have the form for creating a new Lesson, which means every time you upload a file, it will create a new lesson.
Some options to consider are:
Place the upload form in a place that's only available after the Lesson has been created. This lets you create a form_for [#lesson, Attachment.new] which will point to the right URL and let you upload files really quickly, but the Lesson must be created first.
You could adjust the JS not to submit an AJAX request right away and instead attach hidden fields with the image data.
My screencast covered this method because you had to create the Album first before uploading on the Album's show page. I think this ends up being a better user experience so they aren't worrying about file uploads failing and causing their other form data to possibly get lost or not saved.
The problem:
When I'm editing the contents of a nested model, it saves new entries instead of editing the ones already there.
The models:
# job.rb
class Job < ActiveRecord::Base
# Relations
has_many :logs, :dependent => :destroy
accepts_nested_attributes_for :logs, allow_destroy: true, reject_if: proc { |a| a['user_id'].blank? }
end
# log.rb
class Log < ActiveRecord::Base
belongs_to :job
belongs_to :user
# a single user should not be logged more than once per job
validates :user_id, uniqueness: { scope: :job_id }
end
# user.rb
class User < ActiveRecord::Base
has_many :logs
validates_presence_of :name
def self.all_active
User.where( active: 1 )
end
end
The Job controller:
class JobsController < ApplicationController
before_action :set_job, only: [:show, :edit, :update, :destroy]
def index
#jobs = Job.all
end
def show
end
def new
#job = Job.new
10.times { #job.logs.build }
end
def edit
( #job.people - #job.logs.count ).times { #job.logs.build }
end
def create
#job = Job.new(job_params)
# Set the admin id
#job.logs.each do |log|
log.admin_id = current_admin.id
end
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.' }
format.json { render :show, status: :created, location: #job }
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.' }
format.json { render :show, status: :ok, location: #job }
else
format.html { render :edit }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url, notice: 'Job was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_job
#job = Job.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def job_params
params.require(:job).permit(:people, :logs_attributes => [:user_id])
end
end
The Job Form
<%= form_for(#job) do |f| %>
<% if #job.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#job.errors.count, "error") %> prohibited this job from being saved:</h2>
<ul>
<% #job.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="small-3 columns"><%= f.label :people %></div>
<div class="small-9 columns"><%= f.integer :people %></div>
</div>
<table>
<%= f.fields_for :logs do |builder| %>
<%= render 'logs/form', { f: builder } %>
<% end %>
</table>
<div class="actions">
<%= f.submit %>
</div>
The Logs Partial:
<tr>
<td>
<%= f.label :user_id %><br>
<%= f.collection_select(:user_id, User.all_active, :id, :name, { :prompt => 'Select User' } ) %>
</td>
<td>
<%= f.label :performance %><br>
<%= f.number_field :performance %>
</td>
</tr>
Creating the job works fine. I then go to edit the entry. On the job edit screen, I see all of the logs included along with a few remaining blank log entry lines (due to the 10.times #logs.build in the Job controller).
Now, without editing anything, I click submit. I get the following error:
1 error prohibited this war from being saved:
Logs user has already been taken
Additionally, the original entries are shown, and then below them are the same exact entries duplicated, but "red" due to the error. The list of blank entries (from 10.times) is no longer showing.
However, from the editing screen, if I change ALL of the logs' users to something else, I will not get an error. It will instead create new entries with those newly-selected users instead of modifying the current entries.
I hope I've provided enough information to get this resolved! Thanks
So, it turns out that the problem was caused by not whitelisting the :id parameter of the log.
I altered my job_controller:
From:
def job_params
params.require(:job).permit(:people, :logs_attributes => [:user_id])
end
To:
def job_params
params.require(:job).permit(:people, :logs_attributes => [:id, :user_id])
end
That was what was causing the problem with validation! This may be too complex of q/a to help anyone, but hey, it just might!
I'm trying to get categories and subcategories working. So far, I can create categories and add subcategories to them. When I submit the form, the subcategories_attributes send, but no Subcategory records are created. Please help, I'm pulling my hair out over here, and none of the tutorials seem to be helping.
category.rb
class Category < ActiveRecord::Base
has_many :subcategories, :dependent => :destroy
accepts_nested_attributes_for :subcategories, :reject_if => lambda {|a|
a[:content].blank?}
end
subcategory.rb
class Subcategory < ActiveRecord::Base
belongs_to :category
end
categories_controller.rb
class CategoriesController < ApplicationController
before_action :set_category, only: [:show, :edit, :update, :destroy]
def index
#categories = Category.all
end
def show
end
def new
#category = Category.new
#category.subcategories.build
end
def edit
end
def create
#category = Category.new(category_params)
respond_to do |format|
if #category.save
format.html { redirect_to #category, notice: 'Category was successfully
created.' }
format.json { render action: 'show', status: :created, location: #category }
else
format.html { render action: 'new' }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #category.update(category_params)
format.html { redirect_to #category, notice: 'Category was successfully
updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
def destroy
#category.destroy
respond_to do |format|
format.html { redirect_to categories_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_category
#category = Category.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def category_params
params.require(:category).permit(:name, subcategories_attributes: [:id, :name,
:_destroy])
end
end
_form.html.erb
<%= nested_form_for(#category) do |f| %>
<% if #category.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#category.errors.count, "error") %> prohibited this category
from being saved:</h2>
<ul>
<% #category.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<%f.fields_for :subcategories do |builder|%>
<p>
<b>Subcategory</b>
<%=builder.text_field :name%>
<%=builder.link_to_remove "Remove"%>
<p>
<%end%>
<p>
<%=f.link_to_add "Add a Subcategory", :subcategories%>
</p>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Params Hash (on submit):
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"19FxRnWF1F3BD4QZIkkce4arkOPt/BMkWFw6Z+vpV+8=", "category"=>
{"name"=>"Test", "subcategories_attributes"=>{"1398706662184"=>{"name"=>"TS1",
"_destroy"=>"false"}, "1398706664804"=>{"name"=>"TS2", "_destroy"=>"false"}}},
"commit"=>"Create Category"}
Thanks in advance!
subcategories_attributes are sent correctly within your params hash BUT content attribute is missing in them.
"subcategories_attributes"=>{"1398706662184"=>{"name"=>"TS1",
"_destroy"=>"false"}, "1398706664804"=>{"name"=>"TS2", "_destroy"=>"false"}}
Notice there is no content key passed.
So, all the subcategories records passed in subcategories_attributes are REJECTED due to the condition you specified in Category model:
accepts_nested_attributes_for :subcategories, :reject_if => lambda {|a|
a[:content].blank?}
Notice :reject_if => lambda {|a| a[:content].blank?} part above, this will reject all the records for which content is missing.
UPDATE
when I go to my edit action, the fields don't show up, despite being added to the database as intended (and showing up as such in other
forms).
Set a variable in edit and new actions as below:
def new
#category = Category.new
#subcategories = #category.subcategories.build ## Added
end
def edit
#subcategories = #category.subcategories ## Added
end
Update the fields_for in edit form as below:
<%= f.fields_for :subcategories, #subcategories do |builder|%>
How can I upload multiple images from a file selection window using Rails 4 and CarrierWave? I have a post_controller and post_attachments model. How can I do this?
Can someone provide an example? Is there a simple approach to this?
This is solution to upload multiple images using carrierwave in rails 4 from scratch
Or you can find working demo :
Multiple Attachment Rails 4
To do just follow these steps.
rails new multiple_image_upload_carrierwave
In gem file
gem 'carrierwave'
bundle install
rails generate uploader Avatar
Create post scaffold
rails generate scaffold post title:string
Create post_attachment scaffold
rails generate scaffold post_attachment post_id:integer avatar:string
rake db:migrate
In post.rb
class Post < ActiveRecord::Base
has_many :post_attachments
accepts_nested_attributes_for :post_attachments
end
In post_attachment.rb
class PostAttachment < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
belongs_to :post
end
In post_controller.rb
def show
#post_attachments = #post.post_attachments.all
end
def new
#post = Post.new
#post_attachment = #post.post_attachments.build
end
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
params[:post_attachments]['avatar'].each do |a|
#post_attachment = #post.post_attachments.create!(:avatar => a)
end
format.html { redirect_to #post, notice: 'Post was successfully created.' }
else
format.html { render action: 'new' }
end
end
end
private
def post_params
params.require(:post).permit(:title, post_attachments_attributes: [:id, :post_id, :avatar])
end
In views/posts/_form.html.erb
<%= form_for(#post, :html => { :multipart => true }) do |f| %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<%= f.fields_for :post_attachments do |p| %>
<div class="field">
<%= p.label :avatar %><br>
<%= p.file_field :avatar, :multiple => true, name: "post_attachments[avatar][]" %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
To edit an attachment and list of attachment for any post.
In views/posts/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<% #post_attachments.each do |p| %>
<%= image_tag p.avatar_url %>
<%= link_to "Edit Attachment", edit_post_attachment_path(p) %>
<% end %>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Back', posts_path %>
Update form to edit an attachment views/post_attachments/_form.html.erb
<%= image_tag #post_attachment.avatar %>
<%= form_for(#post_attachment) do |f| %>
<div class="field">
<%= f.label :avatar %><br>
<%= f.file_field :avatar %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Modify update method in post_attachment_controller.rb
def update
respond_to do |format|
if #post_attachment.update(post_attachment_params)
format.html { redirect_to #post_attachment.post, notice: 'Post attachment was successfully updated.' }
end
end
end
In rails 3 no need to define strong parameters and as you can define attribute_accessible in both the model and accept_nested_attribute to post model because attribute accessible is deprecated in rails 4.
For edit an attachment we cant modify all the attachments at a time. so we will replace attachment one by one, or you can modify as per your rule, Here I just show you how to update any attachment.
If we take a look at CarrierWave's documentation, this is actually very easy now.
https://github.com/carrierwaveuploader/carrierwave/blob/master/README.md#multiple-file-uploads
I will use Product as the model I want to add the pictures, as an example.
Get the master branch Carrierwave and add it to your Gemfile:
gem 'carrierwave', github:'carrierwaveuploader/carrierwave'
Create a column in the intended model to host an array of images:
rails generate migration AddPicturesToProducts pictures:json
Run the migration
bundle exec rake db:migrate
Add pictures to model Product
app/models/product.rb
class Product < ActiveRecord::Base
validates :name, presence: true
mount_uploaders :pictures, PictureUploader
end
Add pictures to strong params in ProductsController
app/controllers/products_controller.rb
def product_params
params.require(:product).permit(:name, pictures: [])
end
Allow your form to accept multiple pictures
app/views/products/new.html.erb
# notice 'html: { multipart: true }'
<%= form_for #product, html: { multipart: true } do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
# notice 'multiple: true'
<%= f.label :pictures %>
<%= f.file_field :pictures, multiple: true, accept: "image/jpeg, image/jpg, image/gif, image/png" %>
<%= f.submit "Submit" %>
<% end %>
In your views, you can reference the images parsing the pictures array:
#product.pictures[1].url
If you choose several images from a folder, the order will be the exact order you are taking them from top to bottom.
Some minor additions to the SSR answer:
accepts_nested_attributes_for does not require you to change the parent object's controller. So if to correct
name: "post_attachments[avatar][]"
to
name: "post[post_attachments_attributes][][avatar]"
then all these controller changes like these become redundant:
params[:post_attachments]['avatar'].each do |a|
#post_attachment = #post.post_attachments.create!(:avatar => a)
end
Also you should add PostAttachment.new to the parent object form:
In views/posts/_form.html.erb
<%= f.fields_for :post_attachments, PostAttachment.new do |ff| %>
<div class="field">
<%= ff.label :avatar %><br>
<%= ff.file_field :avatar, :multiple => true, name: "post[post_attachments_attributes][][avatar]" %>
</div>
<% end %>
This would make redundant this change in the parent's controller:
#post_attachment = #post.post_attachments.build
For more info see Rails fields_for form not showing up, nested form
If you use Rails 5, then change Rails.application.config.active_record.belongs_to_required_by_default value from true to false (in config/initializers/new_framework_defaults.rb) due to a bug inside accepts_nested_attributes_for (otherwise accepts_nested_attributes_for won't generally work under Rails 5).
EDIT 1:
To add about destroy:
In models/post.rb
class Post < ApplicationRecord
...
accepts_nested_attributes_for :post_attachments, allow_destroy: true
end
In views/posts/_form.html.erb
<% f.object.post_attachments.each do |post_attachment| %>
<% if post_attachment.id %>
<%
post_attachments_delete_params =
{
post:
{
post_attachments_attributes: { id: post_attachment.id, _destroy: true }
}
}
%>
<%= link_to "Delete", post_path(f.object.id, post_attachments_delete_params), method: :patch, data: { confirm: 'Are you sure?' } %>
<br><br>
<% end %>
<% end %>
This way you simply do not need to have a child object's controller at all! I mean no any PostAttachmentsController is needed anymore. As for parent object's controller (PostController), you also almost don't change it - the only thing you change in there is the list of the whitelisted params (to include the child object-related params) like this:
def post_params
params.require(:post).permit(:title, :text,
post_attachments_attributes: ["avatar", "#original_filename", "#content_type", "#headers", "_destroy", "id"])
end
That's why the accepts_nested_attributes_for is so amazing.
Also I figured out how to update the multiple file upload and I also refactored it a bit. This code is mine but you get the drift.
def create
#motherboard = Motherboard.new(motherboard_params)
if #motherboard.save
save_attachments if params[:motherboard_attachments]
redirect_to #motherboard, notice: 'Motherboard was successfully created.'
else
render :new
end
end
def update
update_attachments if params[:motherboard_attachments]
if #motherboard.update(motherboard_params)
redirect_to #motherboard, notice: 'Motherboard was successfully updated.'
else
render :edit
end
end
private
def save_attachments
params[:motherboard_attachments]['photo'].each do |photo|
#motherboard_attachment = #motherboard.motherboard_attachments.create!(:photo => photo)
end
end
def update_attachments
#motherboard.motherboard_attachments.each(&:destroy) if #motherboard.motherboard_attachments.present?
params[:motherboard_attachments]['photo'].each do |photo|
#motherboard_attachment = #motherboard.motherboard_attachments.create!(:photo => photo)
end
end
Here is my second refactor into the model:
Move private methods to model.
Replace #motherboard with self.
Controller:
def create
#motherboard = Motherboard.new(motherboard_params)
if #motherboard.save
#motherboard.save_attachments(params) if params[:motherboard_attachments]
redirect_to #motherboard, notice: 'Motherboard was successfully created.'
else
render :new
end
end
def update
#motherboard.update_attachments(params) if params[:motherboard_attachments]
if #motherboard.update(motherboard_params)
redirect_to #motherboard, notice: 'Motherboard was successfully updated.'
else
render :edit
end
end
In motherboard model:
def save_attachments(params)
params[:motherboard_attachments]['photo'].each do |photo|
self.motherboard_attachments.create!(:photo => photo)
end
end
def update_attachments(params)
self.motherboard_attachments.each(&:destroy) if self.motherboard_attachments.present?
params[:motherboard_attachments]['photo'].each do |photo|
self.motherboard_attachments.create!(:photo => photo)
end
end
When using the association #post.post_attachments you do not need to set the post_id.
i have a form with simple_form gem. if i digit the url in the browser with the anchor tag it works:
localhost:3000/contacts/#new_contact #show me the correct form in the page
this is my controller:
class ContactsController < ApplicationController
def index
#message = Contact.new()
end
def create
#message = Contact.new(msg_params)
#message.request = request
if #message.deliver
redirect_to contacts_path , flash: { success: 'Ok' }
else
render action: :index #how can i render the new_contact anchor??
end
rescue ScriptError
redirect_to contacts_path , flash: { error: 'spam' }
end
private
def msg_params
params.require(:contact).permit(:name,:email,:message,:spam)
end
end
this is my form:
<%= simple_form_for #message, defaults: { label: false} do |f| %>
<%= f.input :name %>
<%= f.input :email %>
<%= f.input :message, :as => :text,input_html: { rows: 7 } %>
<div class="hidden">
<%= f.input :spam, :hint => 'Leave this field blank!' %>
</div>
<%= f.button :submit, 'Send', class: 'btn-block btn-success btn-lg' %>
<% end %>
how can i show the new_contact anchor with the render method?
You can't use render to modify the anchor tag. In fact, render has nothing at all to do with the URI.
You can use existing links to link to "/url#anchor", redirect there, or use javascript to achieve the same effect.
You might also need to add :id => 'anchor' if the anchor itself isn't setup on the form.