Ok guys, so I'm making a scheduler.
So I have two tables so far,
Shows with "title:string" and "description:text" and I also have
ShowTime; with "show_id:integer", "day:string", and "show_time:time".
I did the has_many, and belongs_to, I honestly do not know where to go from here on,
I want a user to be able to add the times when creating a new show. What would I do? I was looking at some rails associations documentations, seems like I would be making something like,
#showtime = #shows.showtimes.create(:show_id => show.id, :day => DAY, :show_time => TIME)
Notice I put just DAY and TIME, because I also honestly don't know how I'll fetch this data.
It really depends on your interface. But for simplicity, let's assume you provided two select boxes for selecting day and time, and have to add ShowTime one by one.
And assume you have rest resources:
map.resources :shows do |show|
show.resources :show_times
end
The form: (given a #show object created already)
<% form_for #show_time, :url => show_show_time_path(#show) do |form| %>
<%= form.label :day %>: <%= form.select :day, [["Mon", "mon"], ["Tue", "tue"]], {} %>
<%= form.label :show_time %>: <%= form.select :show_time, [["Slot 1", "09:00"]], {} %>
<% end %>
You should provide your best way to generate the day & show_time arrays. They are in the following structure:
[["Text", "value"], ["Text", "value"]]
which will generate something like:
<option value="value">Text</option>
After the form is submitted, in your create action:
def create
#show = Show.find params[:show_id] # this params[:show_id] is from the rest resource's path
#show_time = #show.show_times.build(params[:show_time]) # this params[:show_time] is from the form you submitted
if #show_time.save
flash[:notice] = "Success"
redirect_to show_show_time_path(#show, #show_time)
else
flash[:notice] = "Failed"
render :action => "new"
end
end
Related
I'm working on a dynamic form in a Rails app, and I need to insert a variable number of records into a model in a single form submission. I've done this using PHP -> MySQL/Postgres before, but I have no idea how to do it in Rails.
Ultimately, users should be able to create any number of records to be inserted, but in my example below, I'm limiting it to 2... let me see if I can do that, first...
Here's the form - the ids all get a unique suffix because they are being populated dynamically from localStorage objects on submission.
new.html.erb
<%= form_for #entry, html: {id: :new_entry_form} do |f| %>
<% for i in 0..1 %>
<%= f.text_field :name, :id => 'name_#{i}' %>
<%= f.text_field :day, :id => 'day_#{i}' %>
<% end %>
<% end %>
Here's the associated controller - I'm sure that this is missing something, but I don't know what.
def new
#entry = Entry.new
end
def create
#entry = Entry.create(entry_params)
redirect_to "http://localhost:3000/entries"
end
private
def entry_params
params.require(:entry).permit(:name, :day)
end
Any help would be much appreciated.
Follow this link it shows how to create multiple object in one form submit:
http://vicfriedman.github.io/blog/2015/07/18/create-multiple-objects-from-single-form-in-rails/
I'm building a web interface to accompany a mobile app I'm building. I have a drop down select menu that lists a bunch locations.
On selection of a location I want to make a call to a method in my controller and grab some destinations within the location that was selected (each location has several destinations).
I then would like to render my show template with these results allowing the user to select a destination and make a booking.
This is what I have so far:
My view with a list of resorts:
<%= form_tag :url => { :action => :show } do %>
<%= select_tag :resort , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
<% end %>
Controller:
class HomeController < ApplicationController
def index
#resorts = ["A","B", "C", "D", "E"]
end
def new
end
def edit
end
def create
end
def show
#activities = Parse::Query.new("Activity").tap do |a|
a.eq("resort", params[:resort])
end.get
end
end
Just slightly confused. Using form_for makes more sense to me with CRUD in mind and also because the form is object based.
I'd like to just take the selected resorted and pass it into a method in my controller that goes into a database and grabs a bunch of destinations. I then want to list these destinations on my show page where a user can click and be taken to another page where they can make a booking at that destination.
My above code doesn't work. I have resources :home in my routes file.
However when I try to load my page with the form I get:
No route matches {:action=>"show", :controller=>"home"} missing required keys: [:id]
How do I pull this off?
I went on my lynda account and pulled up a rails essential tutorial which I'll have to use to refresh my memory some time tomorrow but the tutor doesn't cover use of select_tag.
Would appreciate some help here
Thanks for your time
So a few thoughts. Not sure why you are using form_tag and also not sure why you aren't using Rails idiomatic conventions.
Declare a resource in your routes for #resorts, like so:
resources :resorts
Then just use Rails form_for helper like:
<%= form_for #resorts, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= f.select :resort, (insert your other options) %>
<%= f.submit "Create" %>
<% end %>
I have not tested the above code, so play around with it, but that should work.
However, let me save you some headache. Checkout SimpleForm.
For your models, you would want to setup an association between your locations and destinations.
class Location < ActiveRecord::Base
belongs_to :resort # or whatever the relation is
has_many :destinations
end
class Destination < ActiveRecord::Base
belongs_to :location # This assumes there is just a one-to-many relationship between Location and Destination
end
Make sure you have a LocationsController with all the actions.
In this case, your SimpleForm form would look something like this:
<%= simple_form_for #locations do |f| %>
<%= f.input :name %>
<%= f.association :password %>
<%= f.button :submit %>
<% end %>
That approach will make your life much easier. Take a look at the collections methods in Simple Form. Rails can make your life difficult with the built in form helpers.
Hope that helps!
In your routes, add
get '/choose_resort' => 'home#show' #you can name the get whatever
Then in your form...
<%= form_tag choose_resort_path do %>
That being said... you should have your query at a separate endpoint, and redirect to the show page. That should get you moving, methinks.
The show action needs an id of the object you are showing. Change your controller:
class HomeController < ApplicationController
def index
#resorts = [["A",1], ["B",2], ["C",3], ["D",4], ["E",5] ]
end
And your view
<%= select_tag :id , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
That gives your show action the proper resort id. You'll have to adjust that action to find the right activities relevant to the resort.
I have my form_tag set up as follows:
<% Rating.find(:all, :conditions => ["recommendation_id = ? and rating_set = ? and product_id = ?", rec.id, params[:rating_set_id], params[:product_id]]).each do |rate| %>
<%= text_field_tag "recommendation_ratings[#{rec.id}][notes]", "#{rate.notes}", :id => "rec_note_text", :placeholder => 'Enter Notes..'%>
<% end %>
This works when the find conditions are met, however before the form is submitted, the recommendation_id is not persisted to the DB, so this find method does not return anything, and this causes my form tag not to render. It only render when all conditions of the find are met. How can I render my form regardless is the find condition is met?
You are using view/controller in a wrong way.
You should define new partial called _rating.html.erb
in there your form_tag (please replace with valid values, I have just put as an example)
<%= text_field_tag "recommendation_ratings[#{id}][notes]", "#{notes}", :id => "rec_note_text", :placeholder => 'Enter Notes..'%>
then, wherever you are rendering that list of Ratings, put for example in ratings/show.html.erb
<%= render #ratings%>
and in Ratings_controller you should put:
define show
#ratings = Ratings.find_all_with_conditions
end
and in model Rating.rb you should put:
define self.find_all_with_conditions
Rating..find(:all, :conditions => []) #put your logics here for finding all
end
I have just wrote just as an example how you should organize it, and I have not looked to put all valid parameters, I have put just for you to see how to organize you view.
I hope it will help.
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 :)
I have a partial in my rails app that loads the vote form (It's just a select with numbers ranging from 1-5). I'm now making another partial that loads up if the user has already voted it's suppose to be an EDIt partial where you get selected the value that you voted and if you wanted to you could change it. But for some reason is not working, here's the code for it.
#Finds the vote by passing the user and the article
<%= #vote = Vote.find_vote_by(current_user,#article) %>
#Renders the partial with the vote variable loaded up with the vote that was found
<%= render :partial => "votes/edit_vote", :locals => {:vote => #vote} %>
And this is the partial
<% form_for(vote, :url => {:controller => 'votes', :action => 'edit'}) do |f| %>
<%= error_messages_for :vote %>
<p><%= f.hidden_field :article_id %></p>
<p>
<%= f.label :value, "Value for the vote: "%>
<%= f.select :value, {"1" => "1","2" => "2","3" => "3","4" => "4", "5" => "5"}, :selected => vote.value %>
</p>
<p>
<%= f.submit "Cloud-it!" %>
</p>
<% end %>
But for some reason the vote variable is not containing anything not the article_id, nor the value method, any ideas?
EDIT1: Per request here's what's debug #vote is outputting (It it indeed a sane value)
attributes:
created_at: 2010-09-02 14:39:04
updated_at: 2010-09-02 14:39:04
id: 1
value: 4
article_id: 1
user_id: 1
attributes_cache: {}
EDIT2
I tried clearing the partial code, in order to output this:
<%= debug #vote%>
<%= #vote.value %>
If i debug #vote it comes out perfect, will all the attributes and such. But whenever i add the second line it, It's not working it tells me that there's no .value, i tried .id, .article and nothing is as if it didn't exist. Any ideas?
EDIT3
Here's the vote by
named_scope :find_vote_by, lambda {|user,article| {:conditions => {:user_id => user, :article_id => article}}}
The reason behind it, it's that named scopes actually return named scopes, and you can't access the attributes just like it were a Vote class. I fixed this by changing the way to retrieve the vote and just forgetting about using that named scope. I accomplished it by using:
<% #vote = current_user.votes.find_by_article_id(#article)%>
which is a Rails method and actually returns a vote class. Then i just passed it to the partial and the magic worked!
Thank you so much to thenduks, without his help i couldn't had done it.
So first thing to fix is this line:
<%= #vote = Vote.find_vote_by(current_user,#article) %>
Should be:
<% #vote = Vote.find_vote_by(current_user,#article) %>
The former is for outputting in ERB and the latter is for executing arbitrary ruby code.
Next, put a line below that like so:
<%= debug #vote %>
And make sure it's a sane value. If not, paste the definition of your Vote class method find_vote_by.
EDIT: In that case it's probably just because using :locals => {...} makes instance variables, so you want #vote in your partial with the form.