My view for the new form is
<h1>Add Form 3C </h1>
<%= form_for([#basiccase, #form3c]) do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :date_of_investigation %>
<%= f.date_select :date_of_investigation, {:include_blank => true, :default => nil} %>
</div>
<div class="actions">
<%= f.submit "Add Form" %>
</div>
<% end %>
My controller for new and create are
def new
#title = "New Form 3C"
#basiccase = Basiccase.find_by_id(params[:basiccase_id])
#form3c = #basiccase.build_form3_c
end
def create
#basiccase = Basiccase.find_by_id(params[:basiccase_id])
#form3c = #basiccase.build_form3_c(params[:form3c])
if #form3c.save
flash[:success] = "Form created!"
redirect_to current_user
else
flash[:warning] ="Failed to create a Form"
render 'users/show'
end
end
I'm unable to get the value of params[:form3c] into the the create controller. when I tried to check puts params[:form3c] it is showing blank. Can Any on help me where i'm wrong
A params key will be based on your class name. Rails expects class names to be mixed case (e.g. BasicCase) and creates the param key by lowercasing and separating the words with an underscore.
You can check this in a Rails console using #underscore:
1.9.2p290 :001 > "BasicCase".underscore
=> "basic_case"
I imagine you have named your class Form3C which becomes form3_c as Dylan suggested.
You may want to consider renaming both your models to BasicCase and Form3c which should give you params basic_case_id and form3c.
Check your console or development.log, just after click on "Add Form" .
Not sure about exact, but You will find parameter something like :
Parameters: {"utf8"=>"Γ£ô", "authenticity_token"=>"...", "basiccase"=>{"form3c" => {"email"=>"asdsa", "password"=>"[FILTERED]", "remember_me"=>"0"}}}
Then use params[:basiccase][:form3c]
Related
I have a form where users look for a particular bill by some attributes of that bill, namely the "Congress Number", "Bill Type", and "Bill Number", as in 114-H.R.-67 . I want to "show" the appropriate bill, but to do that I have get the appropriate bill model in a separate action which I've called "find_by_attributes". Inside this action I perform:
#bill = Bill.find_by( params ).first
which correctly acquires the appropriate bill's id.
Now I simply want to redirect to the "show" method of this bill, as in the url
".../bills/[#bill.id]"
As of right now, at the end of my "find_by_attributes" action I do
redirect_to bills_path(#bill)
which correctly loads the show.html.erb with #bill, but does not change the url (the url is still shows the "find_by_attributes" action followed by a long query-string, instead of the clean "/bills/[:bill_id]".
How can I restructure my code to achieve the neat redirect that I desire?
Full code below:
THE FORM
<%= form_tag("bills/find_or_create", :method => :get ) do |f| %>
<%# render 'shared/error_messages', object: f.object %>
<%= fields_for :bill do |ff| %>
<%= ff.label :congress, 'Congress (i.e. 114)' %>
<%= ff.number_field :congress, class: 'form-control' %>
<%= ff.select :bill_type, options_for_select(
[['House of Representatives', 'hr'],
['Senate', 's'],
['House Joint Resolution', 'hjres'],
['Senate Joint Resolution', 'sjres'],
['House Concurrent Resolution', 'hconres'],
['Senate Concurrent Resolution', 'sconres'],
['House Resolution', 'hres'],
['Senate Resolution', 'sres']]
)
%>
<%= ff.label :bill_number, 'Bill number (i.e. 67)' %>
<%= ff.number_field :bill_number, class: 'form-control' %>
<% end %>
<%= submit_tag "Submit", class: "btn btn-primary" %>
<% end %>
THE CONTROLLER ACTIONS
def find_by_attributes
#bill = Bill.where(bill_params).first_or_create(bill_attributes)
redirect_to bills_path(#bill)
end
def show
puts bill_params
if params[:bill]
#bill = Bill.where(bill_params).first_or_create do |bill|
bill.attributes = bill_attributes
end
else
#bill = Bill.find(params[:id])
end
#subjects = Subject.where("bill_id = ?", #bill[:id])
#bill_comments = Comment.where("target = ?", #bill[:id])
end
ROUTES FILE
...
resources :bills do
get :find_by_attributes
end
...
EDIT
I make use of the turbolinks gem in my rails application.
the thing I see here is that you are calling to
redirect_to bills_path(#bill)
that in theory is not the show path, you just need to remove the "s"
redirect_to bill_path(#bill)
and as a side comment, in this line, you don't need the first part, because find_b, finds the first record matching the specified conditions, you can remove that part.
#bill = Bill.find_by( params )
I've been writing a new RoR app for practice. This is a basic app that is supposed to function as a lookup page for animals.
I've been working on the Create/New functions in the controller for my page. I would like to make it so that a user can enter in an animal, and have the animal save to the SQL database. Afterwards, the page should redirect to the newly created animal page.
Here's my animals_controller.rb:
class AnimalsController < ApplicationController
def index
#animals = Animal.all
end
def show
#animal = Animal.find(params[:id])
end
def new
end
def create
# render plain: params[:animal].inspect
#animal = Animal.new(animal_params)
#animal.save
redirect_to #animal
end
private def animal_params
params.require(:animal).permit(:name, :scientific_name, :range)
end
end
Here is my views/animals/new.html.erb:
<h1> Add Animal </h1>
<%= form_for :animal, url: animals_path do |f| %>
<p>
<%= f.label :name %> <br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :scientific_name %> <br>
<%= f.text_field :scientific_name %>
</p>
<p>
<%= f.label :range %> <br>
<%= f.select :range, ['land', 'sea', 'sky', 'underground'], :prompt => 'Select One' %>
</p>
<p>
<%= f.submit %>
<p>
<% end %>
When I try to enter in a new animal, here is what I get:
<ActionController::Parameters {"name"=>"cat", "scientific_name"=>"Felis catus", "range"=>"land"} permitted: false>
I'm wondering why I keep getting "permitted:false" when I have code in animals_controller.rb that states that these params are permitted! Can anyone point out anything or give me some suggestions?
Your params should look like
<ActionController::Parameters {"animal" => {"name"=>"cat", "scientific_name"=>"Felis catus", "range"=>"land"} } permitted: false>
Also, in the form, can you change :animal to #animal.
Alternatively, you can try this
params.require(:animal).permit(:name, :scientific_name, :range).permitted?
Problem is with this line render plain: params[:animal].inspect
because you are printing/accessing params directly without permission instead use :animal_params
render plain: animal_params.inspect
this lines #animal = Animal.new(animal_params) is fine. I guess your creating process works perfectly only.
I have looked around S.O. and other resources on the web and I am finding other questions that are similar to this one but not exactly like mine. I'm sure that there is a response out there that works but I am asking this question for clarification as much as I am asking to find the solution. Sorry if this sounds redundant to other questions but I have yet to find something that definitively answers my question.
I have an app where businesses have a listing page and each of those pages has a section where users can submit comments about that business.
Each business page is handled via a 'merchants_controller' using the 'show' action:
def show
#merchant = Merchant.merchant_link_test(params[:id])
#title = #merchant.name
# used inside maps javascript
#map_height = '290px'
#map_width = '350px'
#user_reviews = Review.where(:merchant_id => #merchant.id).order("created_at....
#user_reviews_count = Review.where(:merchant_id => #merchant.id).count
#user_or_merchant = 'merchant'
#review = Review.new
#average_rating = Review.where(:merchant_id => #merchant.id).average(:rating)
#rounded = round_rating(#average_rating)
#yelp_query = #merchant.yelp_string
#yelp_count = yelp(#yelp_query, 'avg_rating')
#num_of_yelp = yelp(#yelp_query, 'review_count')
end
I have a partial in the 'show' layout that displays a form for submitting comments about that business. The form input is handled via a 'reviews_controller' using the 'create' action:
def create
user = User.find_by_id(current_user.id)
id = user.id
#merchant = Merchant.find(params[:review][:merchant_id])
params[:review].store(:user_id, id)
#review = Review.new(params[:review])
if #review.save
flash[:success] = "Your review was submitted!"
redirect_to #merchant
else
flash[:error] = "There was an error submitting your review"
render :template => 'merchants/show', :locals => { :id => #merchant.id, }
end
end
The form uses the 'form_for' helper and looks like this:
<% if signed_in? %>
<div class = "comment_form">
<%= form_for #review do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class = "field">
<div id = "required_rating"> * </div><%= f.label :rating %>
</br>
<%= f.select :rating, [['', ''],['1 star (terrible)', 1],
['2 stars', 2],['3 stars', 3],['4 stars', 4],['5 stars
(bomb.com)', 5]] %>
</br>
</div>
<div class = "field">
<div id = "required_comment"> * </div><%= f.label :comment,
"Comment (limit 1000 characters)" %>
<br/>
<%= f.text_area :comment, :cols => 80, :rows => 6 %>
</div>
<div id = "denotes_text"> * Denotes required field </div>
<div class = "actions">
<%= f.submit "Submit Review" %>
<% end %>
<% else %>
<div class = "sign_in_to_comment">
<%= link_to "Sign in to submit a review of this merchant",
signin_path %>
</div>
</div>
<% end %>
I have a two tables and two models, 'merchants' and 'reviews' that handle the data for the respective resources. My 'routes' file looks like this:
resources :merchants, :only => [ :new, :create, :show ]
match '/merchants/:name', :to => 'merchants#show'
match '/merchants/:id/all', :to => 'comments#all_comments_merchant', :as => :all
match '/merchants/:id/map', :to => 'merchants#map', :as => :map
resources :reviews, :only => [ :create ]
My issue is that when a user submits a comment, if an error is generated via my validations in the model, the error object is passed back to the create action in the 'reviews_controller.' I then want to display that error message on the 'merchant_show_page' but need to pass the error object from the 'reviews_controller' back to the 'merchants_controller.'
From what I have read, it seems like the error object has some 'automagic' functionality when being passed between actions within the same controller. Specifically, it seems like the model knows the action that submitted the data and returns the error object using 'render' without having to initialize any instance variables on the page.
A few of the solutions that I have seen regarding similar questions:
1. Move the form submission action into the 'merchants_controller' and lose the
'reviews_controller' altogether.
2. Use 'redirect_to' instead of 'render' and pass the error object as a variable in the
redirect call.
It seems like there has to be an easy, 'rails way' to do this. Having separate controllers seems to make logical sense and it allows me to keep merchants and reviews as separate resources which, from what I have read, is the proper rails convention I should be shooting for. Is this just an issue where there is not a proper 'rails way' to do it? If so, what other rails convention should I be defaulting to?
Any help that can be given would be much appreciated.
Thanks for your help,
noob :)
In a rails project I have two entities, Users and Institutions, they have a many-to-many relationship.
The views for them are set up to create new users and institutions but I want to have another view for linking the two.
In rails console all I have to do is
myuser.institutions << the_institution_i_just_created
The controller can do some of the work but how do I handle the submissions and the forms? I want to use a selection box so that the input is limited to the Institutions already in existence.
<select id="institution_selection" name="institution_sel">
<% selections = []
Institution.all.each do |institution|
pair = [institution.name, institution.id]
selections.concat([pair])
end
%>
<%= options_for_select(selections) %>
</select>
So the question in summary is how do I map this submission to an object so that in the controller I can do add it to the relation?
The solution was:
Alright, so this is the solution I came up with, I'm sure there is a better way to go about it and I'll continue to look into it but at least I got something close to what I was aiming for
def test
if !session[:user]
redirect_to users_path, notice: "Please login first"
end
if params[:institution]
#user = User.find(session[:user])
#institution = Institution.find(params[:institution][:id])
#user.institutions << #institution
redirect_to #user, notice: "Institution was successfully added "
end
end
and for the view
<%= form_tag("/users/test", :method => "post") do %>
<%= collection_select :institution, :id, Institution.all, :id, :name %>
<%= submit_tag("Search") %>
<% end %>
Use collection_select
<% from for #instancevar do |form| %>
<%= form.collection_select :institution_id, Institution.all, :id, :name %>
# Do other stuff....
<% end %>
I have a very common situation and a solution, but I would like to ask the Rails experts out there if it can be improved.
I have a very typical RESTful controller where the user supplies some of the object attributes upon creation. There is a thing model, a ThingsController and various views, including new, create, and a _form partial.
A thing has two attributes,
a color, which is set when they hit a link to create it (i.e. a “Create Red Thing” link that encodes the ID of red as a URL parameter)
a description, which is entered by the user in the form view
I’m happy with the approach for dealing with an attribute like the description that that a user specifies in the form, but less confident about the way that I handle an attribute that is passed through via the URL parameters associated with the first click.
This is what I am doing right now (note that I have omitted error checking to simplify matters). First, my new and create methods in the controller are as follows:
def new
#thing = Thing.new
#thing.color = Color. find(params[:color])
end
def create
#thing = Thing.new(params[:thing])
#thing.color = Color. find(params[:color])
if #thing.save
flash[:notice] = "Successfully created thing."
redirect_to somewhere_url
else
render :action => 'new'
end
end
The new view just invokes the _form partial, which looks as follows:
<% form_for #thing do |f| %>
<%= f.error_messages %>
<%= hidden_field_tag "color", #thing.color.id %>
<%= f.label :description %>
<%= f.text_area :description %>
<%= f.submit "Submit" %>
<% end %>
It seems a little messy to be passing the color ID through to the create method as a URL parameter by putting a hidden field in the form. Does this look reasonable, or is there another approach that would be better?
Normally in this situation, I would put a hidden field in the form, which will hold the color_id. The nice thing about this way is that you can get by with just setting the color of the object before you render the form. So your controller changes to:
def new
#thing = Thing.new
#thing.color = Color. find(params[:color])
end
def create
#thing = Thing.new(params[:thing])
if #thing.save
flash[:notice] = "Successfully created thing."
redirect_to somewhere_url
else
render :action => 'new'
end
end
and your form will change to
<% form_for #thing do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :color_id %>
<%= f.label :description %>
<%= f.text_area :description %>
<%= f.submit "Submit" %>
<% end %>
The color is then passed through both forms, and you only need to retrieve the color in the first form. (Don't forget to add validations your Thing model to make sure it has a valid color though).