I'm creating a landing page and I have two forms on my root page (trying to create a landing page). Very new to ruby on rails so forgive me because I'm going to explain this terribly.
The landing page controller (landing_controller) looks like this:
class LandingController < ApplicationController
def index
#email = Email.new
#design = Design.new
end
end
The emails_controller (emails_controller) looks like this:
class EmailsController < ApplicationController
protect_from_forgery with: :exception
def new
#email = Email.new
end
def create
#email = Email.new(params[email_params])
respond_to do |format|
if #email.save
format.html { redirect_to(root_path, :notice => 'Thank You For Subscribing!') }
format.json { render json: Email.create(email_params) }
else
format.html { redirect_to(root_path)}
format.json { render :json => #email.errors, :status => :unprocessable_entity }
end
end
end
private
def email_params
params.require(:email).permit(:username, :email)
end
end
and the designs controller (designs_controller) looks pretty much the same as emails_controller.
Then I have some validation in the email.rb model:
class Email < ActiveRecord::Base
validates :username, :presence => true
validates :email, :presence => true
end
And again the design.rb looks pretty much the same.
The form I have on the landing page (root_path) index looks like this:
<%= form_for #email, url: emails_path, html: {class: "email-form"} do |f| %>
<% if #email.errors.any? %>
<h3>Error</h3>
<ul>
<% #email.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<h2>Receive Notifications</h2>
<%= f.text_field :username, :class => 'email-box', :placeholder => "First Name", :autocomplete => :off %>
<%= f.text_field :email , :class => 'email-box', :placeholder => "Email", :autocomplete => :off %>
<%= f.submit "Subscribe", :class => 'email-submit' %>
<p class="info">- We'll update you when we launch our new website</p>
<% end %>
When I submit the form breaking the validation I get no errors and if I submit the form following the validation rules I don't know if it creates a new entry in the database. If anyone can help I'd be very appreciative.
you need to render the landing controller index action rather than redirecting to it. because on redirection, it does #email = Email.new and all the errors are gone for email. try this as create action in your emails controller
def create
#email = Email.new(email_params)
respond_to do |format|
if #email.save
format.html { redirect_to root_path, notice: 'Thank You For Subscribing!' }
format.json { render json: Email.create(email_params) }
else
#design = Design.new
format.html { render "landing/index" }
format.json { render :json => #email.errors, :status => :unprocessable_entity }
end
end
end
for success or errors messages, put this in your application.html.erb
<% if flash[:error].present? %>
<p class='flash-error'><%= flash[:error] %></p>
<% end %>
<% if flash[:notice].present? %>
<p class='flash-notice'><%= flash[:notice] %></p>
<% end %>
Related
I am trying to render a partial in my rails app.
I have done this successfully with other partials, but the difference between those that worked and this one is that this partial belongs to a nested model. It is nested inside the model's view that I am trying to use to render the partial.
I have two models, Project and Project_question.
Project has many project questions and accepts nested attributes for project question.
Project question belongs to Project.
My routes are:
resources :projects do
resources :project_questions do
resources :project_answers
end
end
My project question controller has:
class ProjectQuestionsController < ApplicationController
before_action :set_project_question, only: [:show, :edit, :update, :destroy]
# GET /project_questions
# GET /project_questions.json
def index
#project_questions = ProjectQuestion.all
end
# GET /project_questions/1
# GET /project_questions/1.json
def show
end
# GET /project_questions/new
def new
#project_question = ProjectQuestion.new
#project = Project.find(params[:project_id])
# #project_id = params[:project_id]
#project_question.project_answers[0] = ProjectAnswer.new
end
# GET /project_questions/1/edit
def edit
end
# POST /project_questions
# POST /project_questions.json
def create
#project_question = ProjectQuestion.new(project_question_params)
#project_question.project_id = project_question_params[:project_id]
respond_to do |format|
if #project_question.save
format.html { redirect_to project_url(Project.find(project_question_params[:project_id])), notice: 'Project question was successfully created.' }
format.json { render action: 'show', status: :created, location: #project_question }
else
format.html { render action: 'new' }
format.json { render json: #project_question.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /project_questions/1
# PATCH/PUT /project_questions/1.json
def update
respond_to do |format|
if #project_question.update(project_question_params)
format.html { redirect_to #project_question, notice: 'Project question was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #project_question.errors, status: :unprocessable_entity }
end
end
end
# DELETE /project_questions/1
# DELETE /project_questions/1.json
def destroy
#project_question.destroy
respond_to do |format|
format.html { redirect_to project_questions_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project_question
#project_question = ProjectQuestion.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_question_params
params[:project_question].permit(:id, :title, :content, :project_id, :user_id,
project_answer_atttibutes: [:id, :answer, :project_question_id, :user_id]
)
end
end
My project question form has:
<%= simple_form_for [#project, #project_question] do |f| %>
<%= f.input :project_id, as: :hidden, input_html: {value: #project.id} %>
<%= f.input :title, label: 'Question:', :label_html => {:class => 'question-title'}, placeholder: 'Type your question here', :input_html => {:style => 'width: 100%', :rows => 4, class: 'response-project'} %>
<%= f.input :content, label: 'Is there any context or other information?', :label_html => {:class => 'question-title'}, placeholder: 'Context might help to answer your question', :input_html => {:style => 'width: 100%', :rows => 5, class: 'response-project'} %>
<br><br><br>
<%= f.button :submit, 'Send!', :class => "cpb" %>
My project question partial has:
</div>
<div class="generaltext">
<%= #project.project_question.try(:content) %>
</div>
Inside my project#show, I try to render the protect question partial as follows:
<%= render 'project_questions/pqps' %>
and the project_questions/_pqps.html.erb file contains:
<div class="containerfluid">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="categorytitle">
<%= #project.project_question.title %>
</div>
<div class="generaltext">
<%= #project.project_question.try(:content) %>
</div>
<span class="editproject">
<% if current_user.id == #project.creator_id %>
<%= link_to 'Answer this question', new_project_question_project_answer_path(:project_quesetion_id => #project_question.id) %>
<% end %>
</span>
</div>
</div>
</div>
The error message I get when I try is:
undefined method `project_question' for #<Project:0x0000010d8bad40>
My problem was the has_many relationship between project and project questions. I had to make a loop to show each question.
This worked for me:
<% #project.project_questions.each do |singleQuestion| %>
<div class="categorytitle">
<%= singleQuestion.title %>
</div>
<div class="generaltext">
<%= singleQuestion.try(:content) %>
</div>
I'm not sure what is happening here. I've checked everything here but I'm getting this double file upload field:
Even if I use only one field it still renders two images.
_form.html.erb:
<%= nested_form_for #home, :html=>{:multipart => true } do |f| %>
<% if #home.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#home.errors.count, "error") %> prohibited this blog from being saved:</h2>
<ul>
<% #home.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.fields_for :attachments do |attachment_form| %>
<%= attachment_form.file_field :file %>
<br /><br />
<%= attachment_form.link_to_remove "Remove this attachment" %>
<% for attachment in #home.attachments %>
<div class="show_image">
<%= image_tag attachment.file_url(:thumb).to_s %>
</div>
<% end %>
<% end %>
<br /><br />
<%= f.link_to_add "Add attachmnt", :attachments %>
</p>
<br /><br />
<p><%= f.submit %></p>
<br /><br />
<% end %>
Models:
attachment.rb:
class Attachment < ActiveRecord::Base
attr_accessible :description, :file
belongs_to :attachable, :polymorphic => true
mount_uploader :file, FileUploader
end
home.rb:
class Home < ActiveRecord::Base
attr_accessible :body, :attachments_attributes
has_many :attachments, :as => :attachable
accepts_nested_attributes_for :attachments, :allow_destroy => true
end
homes_controller.rb:
class HomesController < ApplicationController
# GET /homes
# GET /homes.json
def index
#homes = Home.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #homes }
end
end
# GET /homes/1
# GET /homes/1.json
def show
#home = Home.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #home }
end
end
# GET /homes/new
# GET /homes/new.json
def new
#home = Home.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #home }
end
end
# GET /homes/1/edit
def edit
#home = Home.find(params[:id])
end
# POST /homes
# POST /homes.json
def create
#home = Home.new(params[:home])
respond_to do |format|
if #home.save
format.html { redirect_to #home, :notice => 'Home was successfully created.' }
format.json { render :json => #home, :status => :created, :location => #home }
else
format.html { render :action => "new" }
format.json { render :json => #home.errors, :status => :unprocessable_entity }
end
end
end
# PUT /homes/1
# PUT /homes/1.json
def update
#home = Home.find(params[:id])
respond_to do |format|
if #home.update_attributes(params[:home])
format.html { redirect_to #home, :notice => 'Home was successfully updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => #home.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /homes/1
# DELETE /homes/1.json
def destroy
#home = Home.find(params[:id])
#home.destroy
respond_to do |format|
format.html { redirect_to homes_url }
format.json { head :no_content }
end
end
end
How do I stop this from happening?
Any help with this would be great, I've been looking at this for hours!
My first guess would be bad data created while getting this set up. Maybe there are previous attachments on the Home object that are not being displayed correctly, but still exist in the database. Does the same problem happen if you create a new Home and attempt to add attachments?
The fields_for block is creating a button and a display of each photo for each attachment it's being passed. I think that's why you're seeing the duplication. The fields_for is an iterator on attachments with a duplicate iterator inside it (for attachment in #home.attachments).
I am totally new to programming and I am having trouble. About 10 days ago I started the UT-Rails course on ureddit.com hosted by Richard Schneeman. So far it has been going very well, but I am on week 5 and having trouble. You'll have to excuse me if I don't use the right terminology, as it has been a lot to take in.
https://github.com/zkay/move_logic_to_controllers is the tutorial I am following at the moment.
I am up to step 2. I have replaced the text in app/views/products/new.html.erb with the following:
<%= form_for(#product) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :price %><br />
<%= f.text_field :price %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
However, when I try to add a new product per the tutorial, the rejection I get back is:
NoMethodError in Products#create
Showing C:/Sites/move_logic_to_controllers/app/views/products/create.html.erb where line #3 raised:
undefined method `name' for nil:NilClass
Extracted source (around line #3):
1: <h2>Product Created Successfully<h2>
2:
3: <%= #product.name %> added to the website, it costs: $<%= #product.price %>
Rails.root: C:/Sites/move_logic_to_controllers
If I remove the .name and .price calls the page works, but it doesn't display any of the data I submitted.
In app/controllers/product_controller.rb I have the following:
class ProductsController < ApplicationController
def index
#products = Product.includes(:user).all
end
def new
#product = Product.new
end
respond_to do |format|
if #product.save
format.html { render :action => "create" }
format.json { render :json => #product }
else
format.html { render :action => "new" }
format.json { render :json => #product.errors, :status => :unprocessable_entity }
end
end
end
Sorry if this is long winded. I appreciate any help.
it should be <%= #products.name %>
/app/views/products/create.html.erb
You don't want to use create.html.erb.
class ProductsController < ApplicationController
def index
#products = Product.includes(:user).all
end
def new
#product = Product.new
end
def create
#product = Product.new(params[:product])
if #product.save
redirect_to products_path, notice: "You added product"
else
flash[:error] = "Something wrong!"
render :new
end
end
end
If you use Rails 4 use:
def create
#product = Product.new(product_params)
if #product.save
redirect_to products_path, notice: "You added product"
else
flash[:error] = "Something wrong!"
render :new
end
end
private
def product_params
params.require(:product).permit(:name, :price)
end
I can't seem to get the flow to work right here. I have a Ruby on Rails (2.3.9) application. For the purposes of this question we have only a couple of resources. Boxes and Messages.
Box has_many :messages
Message belongs_to :box
I have created a view located at /boxes/1/new_message where I have the below form_for code. I can successfully create a message from this view. The problem arrises when my validations kick in.
In this case, message.body can't be blank and is validated by message.rb. Once this validation happens, it kicks the user over to the Message.new action and upon successfully filling in the message.body the app can no longer find the #box.id to place in message.box_id.
I have tried just about everything I can think of by not sure how to allow a users to receive a validation and still successfully create a message for a box. See my code below for reference.
/views/boxes/new_message.html.erb
<% form_for [#box, Message.new] do |f| %>
<%= f.error_messages %>
<%= f.label :message_title %>
<%= f.text_field (:title, :class => "textfield-message grid_12 alpha") %>
<%= f.label :message_body %>
<%= f.text_area (:body, :class => "textarea-message grid_12 alpha ") %>
<%= f.submit "Add a Message", :class => 'input boxy' %>
<% end %>
messages_controller.rb
def create
#message = Message.new(params[:message])
#box = Box.find(params[:box_id])
#message = #box.messages.build(params[:message])
#message.user = current_user
respond_to do |format|
if #message.save
flash[:notice] = 'Message was successfully created.'
format.html {redirect_to #box }
else
format.html { render :action => "new" }
format.xml { render :xml => #flash.errors, :status => :unprocessable_entity }
end
end
end
def new
#message = Message.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #message }
end
end
I believe your
#box = Box.find(params[:box_id])
should be
#box = Box.find(params[:id])
I have method in my controller:
def work_here
#company = Company.find(params[:id])
current_user.work_apply(current_user, #company)
redirect_to company_path
end
On my view:
<%= render 'companies/work_form' if signed_in? %>
_work_form.html.erb:
<%= form_for company, :remote => true, :url => { :controller => "companies", :action => "work_here" } do |f| %>
<%= f.hidden_field :id, :value => company.id %>
<%= f.submit "I working here" %>
<% end %>
And I have a work_here.js.erb file:
$("#work_at_form").html("<%= escape_javascript("render('companies/works')") %>")
But my form works without ajax request(in other pages ajax forks fine), my js.erb file never use.
Can anyone give me advise?
Thanks.
The work_here.js.erb can't be read because you never call it. A redirect is allways do. render it when the request is js format.
def work_here
#company = Company.find(params[:id])
current_user.work_apply(current_user, #company)
respond_to do |format|
format.html { redirect_to company_path }
format.js { render }
end
end