Rendering a form from another controller in Ruby on Rails 4 - ruby-on-rails-4

I am trying to show a form on the contact page, but it is from another controller.
The current code results in "First argument in form cannot contain nil or be empty"
After searching it looks there is a problem with the local hash that is not passed.
How can I correctly pass the locals with this code so that it works?
inquiries_controller.rb
class InquiriesController < ApplicationController
def new
#inquiry = Inquiry.new
end
def create
#inquiry = Inquiry.new(params[:inquiry])
if #inquiry.deliver
render :thank_you
else
render :new
end
end
end
inquiries_form.html.erb
<%= form_for #inquiry do |f|
f.text_field :name
f.text_field :email
f.text_area :message
f.submit "Send"
end %>
static_pages\contact.html.erb
<%= render "inquiries/form",
:inquiry => #inquiry %>

HI try adding this to your StaticPages Controller
class StaticPagesController < ApplicationController
def contact
#inquiry = Inquiry.new
end
end
Its a very common mistake. Also I believe your form may also be wrong unless you are using a gem that allows for that type of form. Let me know if this will fix your error.

Related

Nested attributes showing when editing but not when creating a new record in rails

When I edit a model with nested attributes everything works perfectly. If I try to create a new record with nested attributes, the nested attributes don't appear on the form that has the nested attributes. I have two models as follows
class JobSpec < ActiveRecord::Base
has_many :availabilities
accepts_nested_attributes_for :availabilities, allow_destroy: true
end
and
class Availability < ActiveRecord::Base
belongs_to :job_spec
end
in the job_specs_controller I have
class JobSpecsController < ApplicationController
def new
#job_spec = JobSpec.new
#availabilities = Availability.none
availability = Availability.new
availability.job_spec = #job_spec
#availabilities << availability
end
def edit
#job_spec = JobSpec.find(params[:id])
#availabilities = #job_spec.availabilities
end
def job_spec_params
params.require(:job_spec).permit(
... all of the job_spec attributes,
availabilities_attributes: [:id, ... all of the availability attributes],
)
end
end
In _form for job_spec I have
<% #availabilities.each do |availability| %>
<%= f.fields_for availability do |builder| %>
<%= render partial: 'availabilities/form_mini',
locals: {f: builder, availability: availability} %>
<% end %>
<% end %>
Since editing works, I assume there's not much wrong. Any ideas?
Update
I've almost sorted out all the problems but still have one. Here's what I've done.
1) I had to build the job_spec availabilities. The new action of the JobSpecsController now looks like this
def new
#job_spec = JobSpec.new
#job_spec.client_id = params[:client_id]
#job_spec.availabilities.build
end
2) I wanted to be able the destroy the nested models, so I had to pass :_destroy in with the nested attributes to job_spec_params. That method looks like this
def job_spec_params
params.require(:job_spec).permit(
... all of the job_spec attributes,
availabilities_attributes: [:id, :_destroy, ... all of the availability attributes],
)
end
end
3) Finally, I had to change _form for job_spec. I have
<%= f.fields_for :availabilities do |builder| %>
<%= render partial: 'availabilities/form_mini', locals: {f: builder} %>
<% end %>
The only issue I have now is that I want to pass and instance variable through to my availability partials. Something like this
<%= render partial: 'availabilities/form_mini', locals: {f: builder, a: availability} %>
How should that be done? I'm not sure how to iterate over all the #availabilities while rendering all the partials.
Glad you worked some of the issues out. First one small improvement
#job_specs_controller.rb
def new
#job_spec = JobSpec.new(client_id: params[:client_id])
#job_spec.availabilities.build
end
And to overcome your last issue, the solution is a mix of what you had before and after. You can pass the actual object in the fields_for method. It's like that:
#_form.html.erb
<% #job_spec.availabilities.each do |availability| %>
<%= f.fields_for :availabilities, availability do |builder| %>
<%= render partial: 'availabilities/form_mini',
locals: {f: builder, a: availability} %>
<% end %>
<% end %>

Rails 4 build_association

in my rails 4 app, i have a user model that has_one profile model which also belongs_to the user model
this is my first time using a nested resource so im kinda lost to it
here how it goes
, a user creates an account,after succesful email authentication , user proceed to create a profile. Problem is, im getting error on using the build_association. Im not sure whether the problem is actually that or im getting null values on the params(which i think not)
in my routes.rb
resources :users do
resources :profiles
end
profiles view, new.html.erb
<%= form_for(#profile,url:{ :controller => 'profiles', :action => 'create'},html: {class: "ui large segment form error"}) do |f| %>
<%= render 'shared/form_error_messages', object: f.object%>
<div class="ui horizontal divider">Create a Profile</div>
<%= f.text_field :first_name, :placeholder => "First Name" , :required => true%>
<%= f.submit "Submit Profile", class: "ui submit button"%>
<% end %>
profiles_controller.rb
def new
#user = User.find(params[:user_id])
#profile = #user.build_profile
end
def create
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile has been created"
redirect_to root_url
else
render 'new'
end
end
private
def profile_params
params.require(:profile).permit(:first_name)
end
when im submitting the form, im getting
NoMethodError in ProfilesController#create
undefined method `build_profile' for nil:NilClass
Application Trace | Framework Trace | Full Trace
app/controllers/profiles_controller.rb:9:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"MFCANYra..",
"profile"=>{"first_name"=>"sample",
"commit"=>"Submit Profile",
"user_id"=>"1"}
Try changing the create action in profiles_controller.rb as below :-
def create
#user = User.find(params[:profile][:user_id])
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile has been created"
redirect_to root_url
else
render 'new'
end
end
let me know this worked or not, try to find if something else is causing the problem, thanks.

Rails 4 Search By Category

I want to put a search form on my homepage at pages#home. I'd like to be able to search my model by category. I haven't been able to find a solution where you're actually putting the logic on a different controller than the models you're searching on. I was wondering if someone could help with the syntax and where it needs to go. Here are my relations:
vendor.rb
class Vendor < ActiveRecord::Base
validates :category_id, presence: true
belongs_to :category
end
category.rb
class Category < ActiveRecord::Base
has_one :vendor
end
pages_controller.rb
def home
#vendors = Vendor.all
end
routes.rb
root 'pages#home'
I'm trying to put the search form on home.html.erb, which is under the pages layouts. Was hoping someone could help with how I can accomplish this. This being (seemingly) a simple type of search, I'd hopefully not have to use a gem.
EDIT: ANSWER
For those searching, here's what worked. Thank you #Vla
vendors_controller.rb
def search
#vendors = Vendor.search(params)
end
pages/home.html.erb (this is my root 'pages#home')
<%= form_tag vendors_search_path, method: :get do |f| %>
<%= text_field_tag :search, params[:search], placeholder: "Search Vendors" %>
<%= select_tag 'category', options_for_select(Category.all.map{|el| [el.name, el.id]}) %>
<%= submit_tag 'Search' %>
<% end %>
routes.rb (make sure to put this near the top)
get 'vendors/search'
vendors/search.html.erb
<% #vendors.each do |vendor| %>
<%= vendor.name %>
<%= vendor.phone %>
<%= vendor.email %>
<% end %>
Ok, You can do it this way:
Go to Your vendor.rb file and add search method like this:
def self.search params
vendors = Vendor.where(category_id: params[:category].to_i) unless params[:category].blank?
vendors
end
Then in Your vendors_controller create search method:
def search
#vendors = Vendor.search(params)
end
Then create form at homepage similar to:
= form_tag search_vendors_path, method: :get, role: 'form' do
.form-group
%label Category
= select_tag 'category', options_for_select(Category.all.map{|el| [el.name, el.id]}), class: 'form-control'
= submit_tag 'Search'
And do not forget to put
get 'vendors/search'
into Your routes and add "search" view.
You can still do the same without search action, with result on Your homepage. Anyway I hope You got the idea.

ActionController::ParameterMissing in NamesController#create

Hello there i have been having problems trying to get my Name added onto my index.html via the new.html using form_for kindly look into the code below and correct my code please
My controller
def new
#post = Name.new
end
def create
#post = Name.new(post_params)
if #post.save
redirect_to names_path, notice: "your name was added"
else
render "new"
end
end
def post_param
params.require(:post).permit(:name)
end
My new.html.erb
<h1> Add your name </h1>
<%= form_for #post do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit "Add your name" %>
<% end %>
I am having trouble in this lower part when i click the f.submit (the button that appears in the htlm) it throws me the error.
Your new and create methods should look like this
def new
#post = Post.new #here
end
def create
#post = Post.new(post_params) #here
if #post.save
redirect_to names_path, notice: "your name was added"
else
render "new"
end
end
You are confused of using attribute names with model name.You should be looking at these Guides.It should help you.
Update
As you said you created a Name model,you shouldn't be creating an attribute which is same as your model name.
Solution
Either change your attribute name or model name to some other meaningful name.

saving empty records via form_for - wrong number of arguments

Update: Zishe figured it out. Correct params.require code should be:
def adventure_params
params.require(:adventure).permit(:story, :choice, :parent_id, :user_id)
end
with parenthesis instead of a bracket, of course.
Original question:
I am making a form_for that should be submitting 4 attributes to the Adventure model. The adventure model has ancestry. I keep getting wrong number of arguments (4 for 1) based on my params.require method. When I change to requirements down to 1, I see that all the attributes are blank in my database. I know they are in the params but for some reason they are not being saved. Here is my code:
Form
<div class="form">
<%= form_for #adventure do |f| %>
<%= f.label :choice %>
<%= f.text_area :choice %>
<%= f.label :story %>
<%= f.text_area :story %>
<%= f.label :parent_id %>
<%= f.text_field :parent_id %>
<%= f.submit "Post"%>
<% end %>
</div>
Controller
class AdventuresController < ApplicationController
before_filter :authenticate_user!
def home
end
def index
end
def new
#parent_id = params[:parent_id]
#adventure = Adventure.new
end
def show
#adventure = Adventure.find(params[:id])
end
def create
#user = current_user
#adventure = current_user.adventures.build(adventure_params)
if #adventure.save
flash[:success] = "Adventure created!"
redirect_to #adventure
else
flash[:error] = "There was an error"
redirect_to adventures_path
end
end
private
def adventure_params
params.require(:adventure).permit[:story, :choice, :parent_id, :user_id]
end
end
Model
class Adventure < ActiveRecord::Base
has_ancestry
belongs_to :user
validates :user_id, presence: true
validates :parent_id, presence: true
end
I have no idea why I am getting wrong number of arguments since the attributes show up in the params.
Change permit[...] to:
.permit(:story, :choice, :parent_id, :user_id)