Parent-Child form - ruby-on-rails

How do I show a parent-child relationship on a single page in Rails? I don't need a form as I simply want to show the information (no edits or updates required). The parent is customer and the child is orders. I want to able to select a customer, display some customer information such as address, and list all orders placed in row format. Thanks.

It isn't entirely clear what you want here. I am assuming you want to have a list of customers, and when you click on one of them, other page is being populated with its details. If so, the nicest solution is to use Ajax event which will get the details from a server and place it in given div. Action in customers_controller would be sth like:
def details
#customer = Customer.find(params[:id])
render 'details', :layout => false # remember to add view 'details'
# and appropriate route in routes.
end
and javascript (jQuery) (note it is not perfect ajax call, it doesn;t handle multiple clicks and other problems, but shoud get you started)
$('.customer-row').click(function() {
customer_id = $(this).data('id');
$.ajax({
url: "/customers/" + customer_id + "/details",
type: "get",
success: function(details) {
$('#customer_details').html(details)
}
});
});
Then in your basic view you need to have div with id 'customer_details' somewhere and each of customer row should look like class="customer-row">.
In terms on how to access child objects inside details view it is as simple as:
<% #customer.orders.each do |order|>
# display order
<% end %>

Assuming you have your model associations set up properly..
In the controller,
#customer = Customer.find(params[:id])
#orders = #customer.orders.all
Then in the view, use the orders variable.

Related

Is their any way?I could get the value of dropdown to use in controller using onchange event handler in ruby on rails application

I want to call a method using onchange event handler when a user changes the value on a dropdown.Below is the code for my dropdown box.
<%= select_tag :name,options_for_select(#tests.map{|u| [u.name]}.uniq),:onchange => 'update_dropdown(:name)' %>
In the controller i want a method.which takes the value of selection in dropdown as paramater:
Below code searches database for the document with value of the parameter given from view.And return the document.What are the changes i have to make to get the selection in the controller as the dropdown values are changed!
def update_dropdown(name)
#drop = Test.where("name" => name)
end
How to get the selection value from view into the controller as parameter?
I has a mongoDatabase with documents(row) consisting key named:name.I has 4 unique values under key name.I want user to select the value using dropdown.As the user selected the dropdown.Without page refresh the documents consisting values selected with the key name should be displayed.
Ex:under key name.I has four values for 200 documents.named:
["value1","value2","value3","value4"].These values are the options
for dropdown menu.If user selected any of the values.The documents consisting value for key name should be displayed.
All you need to make ajax call on onchange event. Here is a link to a helpful answer
stackoverflow.com/a/7952315/4136098
How to get the selection value from view into the controller as parameter
Only way is to send the data through either an HTTP or Ajax (XML) request.
Because you've not explained your user story very well, I'll explain the overall schematics on how to get it to work...
Stateless
HTTP makes Rails applications stateless - meaning that each time you send interactions to it, it will have to rebuild the user environment each time (this is why sessions are so important to Rails).
This means that each time you want to invoke new actions / methods, you have to send a request to your server. The request can be sent over several protocols (HTTP, XML and Websockets) - each has the same pattern: Request > Logic > Output
Thus, if you want to send data to your controller, you'll have to either have a full page refresh (follow the above pattern), or send the data via ajax.
Ajax
In this case I'd recommend using ajax to send a request to your controller.
# View
<%= select_tag :name,options_for_select(#tests.map{|u| [u.name]}.uniq), id: "select" %>
#app/assets/javascripts/application.js
$(document).on("change", "#select", function(e) {
$.get("/controller/update_dropdown", {id: $(this).val() }, function(data) {
# Do something here
});
});
This will allow you to use the following:
#config/routes.rb
resources :controller do
get :update_dropdown, on: :collection #-> url.com/controller/update_dropdown
end
#app/controllers/controller_controller.rb
class ControllerController < ApplicationController
def update_dropdown
# params[:id] will be available
#test = Test.find params[:id]
render json: #test.to_json
end
end

using rails how do i only show the id submitted via a text box from a table

I've got a table full of information at the moment, Ideally i need the information from a database table to be viewed via a link.
I only have the controller and some standard html (the html is just a h1 tag at the moment)
The HTML will be standard throughout like a template.
The way i'm seeing what i want in my head is the users will get a link which would be events_prev/{{id from DB here}} and depending on the ID the information on the page will be populated from the corrisponsing DB Row
Heres my controller
class Events::EventsPrevController < ApplicationController
def index
#events = Event.where(id: id)
end
def show
render :nothing => true
end
end
Sorry if its super confusing.
Welcome to rails.
Ok, there's a couple of things that will get you in the right directions. Firstly, you REALLY need to do a little reading to understand how the controller and the routes and the views are linked together in rails, that'll help you tons.
But moving on to your specific issues:
Parameters:
All data passed via a url (get, post, put, doesn't matter the method) is available in the controller in an array object called params - So that means when want to access the data the user submitted, you'll use something like
#event = Event.where(id: params[:id])
Routes:
It looks like you're trying to use the index page. In rails index is a RESTful route which generally points to a collection of model objects. The show route will point to an individual object so you should instead make your link point to the show path instead of the index path.
You can view the routes available on a model on a command line using:
bundle exec rake routes
An example of what your routes might look like:
prev_events GET /prev_events(.:format) prev_events#index
POST /prev_events(.:format) prev_events#create
new_prev_event GET /prev_events/new(.:format) prev_events#new
edit_prev_event GET /prev_events/:id/edit(.:format) prev_events#edit
prev_event GET /prev_events/:id(.:format) prev_events#show
PATCH /prev_events/:id(.:format) prev_events#update
PUT /prev_events/:id(.:format) prev_events#update
DELETE /prev_events/:id(.:format) prev_events#destroy
Link
Based on the routing table, you now should see that the link you need your users to click on might look like this (given that event is your object:
<%= link_to event.title, event_path(event.id) %>
or shortcutted
<%= link_to event.title, event %>
View
For the view this is entirely dependent on the data in the Event model. Since the data is stored in #event you'll simple use the attributes on the event model to render the html however use like, e.g.
<h3><%= #event.title %></h3>
<span><%= #event.start_time %></span>
You should read up on Rails controllers: by default the action index is used to show all of the records and what you're talking about should belong to the show action. The default routes take care of the id passing to your show action.
Index action is mean to show list of items in view and Show action is used to show a single item.
what you are doing in index is actually mean to be in show action.
Reason:
#events = Event.where(id: id)
this line will give u a single record in every case it means it should be in Show action.
your code should look like:
def show
#event = Event.find(params[:id])
[your logic: what you want to do with that #event]
end

How to get 1st nested object into a 2nd level nested object controller?

I have a Character model that has a show page. On the show page, I have a loop of comments that are dynamically generated via a partial. In that comments partial, I have another partial for votes, which contains voting buttons. Naturally, I want to allow votes on comments.
I am unsure how to get the comment object into the votes controller (or VotesController module, depending on the implementation) for creating a vote.
Getting the character object id to the votes controller is simple enough, since the actual view is the character show page, but obtaining a specific comment's id that is genrated from a partial, by clicking a vote button in a partial that is nested in the comments partial is causing me to draw a blank for the syntax of accessing that comment.
(I am using acts_as_votable for votes, and acts_as_commentable for comments.)
app/views/characters/show.html.haml
= render partial: 'comments/comment', collection: #comments, as: :comment
app/views/comments/_form.html.haml
.comment{ :id => "comment-#{comment.id}" }
%hr
= render partial: 'votes/vote_comment'
%h4
#comment body
app/views/votes/_vote_comment.html.haml
.vote-comment-buttons
= link_to image_tag("upvote.png"), votes_upvote_path(), method: :post, remote: true
= link_to image_tag("downvote.png"), votes_downvote_path(), method: :post, remote: true
app/controllers/votes.html.haml
VotesController < ApplicationController
def upvote
# Need the specific comment or comment id whose vote button was clicked.
end
def downvote
# Need the specific comment or comment id whose vote button was clicked.
end
end
Well, here are the basic tips:
You can not pass ruby objects through HTTP, but you can pass id and type of them to build them in your controller.
Even when you type something like comment_path(comment), only id of that comment is passed to your action. That is easily checked by observing your action code (it should contain something like Comment.find(params[:id])).
Passing any desired amout of additional parameters can be done with just providing them to your route helpers, like that: some_voting_path(commentable_id: 14, commentable_type: 'character').
You can access that params inside of your action with params['commentable_type'] or whatever values you pass with your URL. In case you follow passing id and type approach, you should be able to do some metaprogramming:
def upvote_method
model = params[:commentable_type].camelize.constantize # => e.g., Post
object = model.find(params[:commentable_id]) # => post object
# here goes your inner logics
end
Beware that in case you send your request using GET method, these params are gonna be shown in your browser URL. However, you should not use GET for your purpose here, as voting changes the state of objects in your database.

Rails don't reload session-data immediately after AJAX call but only on reloading whole page?

Basically, I have multiple-select box in the page. When the select box is changed, i want to put in session all id's being selected (one or more). The reason why i need something like that is following:
While creating new product user can create many variants of that product based on selected options(for example: Color and Size)(id's mentioned above).
So for example one product can have 2 variants(T-shirt in black color with size XL and green T-shirt with size L)
First of all i created POST route in products controller on which through AJAX i will send selected options:
resources :products do
collection do
post 'ajaxify_options'
end
end
Ajax code
$('#variant-options').change(function() {
var option_values = [];
$("#variant-options option:selected").each(function() {
option_values.push($(this).val());
});
$.ajax({
url: '/products/ajaxify_options',
type: 'POST',
data: ({'ids': option_values})
});
});
ajaxify_options action
def ajaxify_options (inside product controller)
set_option_values params[:ids]
head :ok, :content_type => 'text/html'
end
Here set_option_values is method in ApplicationController defined as:
def set_option_values option_values
session[:option_values] = [] if session[:option_values].nil?
session[:option_values] = option_values
end
with get method also (implemented as helper_method inside ApplicationController)
def get_option_values
return [] if session[:option_values].nil?
session[:option_values]
end
So now when user choose option (one or more) through get_option_values i can access to selected options from anywhere i need (partials for creating new product and variants).
Main-problem: When user select one or more options, through debugging i see that there is NO errors with ajax or server-side code everything is just fine and i can inspect values of selected options. But rails DO NOT reload session data immediately after AJAX call BUT only when i reload whole page.
Side-problem: Is everything fine with this code, i don't know why i think that I violate some Rails practices with populating session through ajax?
Similar question that i find is: Rails not reloading session on ajax post
I tried that solution but result is same.

Rails 3 rateable model - How to create ajax rating?

How do I create some simple ajax rating like there is on this page http://watir.com/documentation/ ? Every visitor should be able to rate, I dont need to set permissions. I want to store the ratings in a column. So the user can sort by ratings.
Please make an detailled example. I am not a javascript expert.
I have found an example to create ratings from scratch. But it authorizes a user.
Can someone show me a guidance to create ratings without a Rater (user)? It should not only store the values but also count the votes.
http://eighty-b.tumblr.com/post/1569674815/creating-an-ajaxified-star-rating-system-in-rails-3
What I did recently to add a simple rating mechanism to an existing project was the following:
I added two fields to an existing table (which contained the items to be rated). Those were:
rating_score => The current score
ratings => The number of ratings which led to the score
For example, if five users would've voted "5" for the current item, rating_score would be 25, and ratings would be 5. The current rating would be computed as rating_score / ratings.
Then I added a new method to the controller of the items to be rated, called "rate", which looked something like:
def rate
#item = Item.find(params[:id])
#container = "item"+#item.id.to_s
#item.rating_score += params[:rating].to_i
#item.ratings += 1
#item.save
respond_to do |format|
format.js
end
end
My view for that method, called rate.js.erb, would look something like
$('#<%= #container %>').html('<%= escape_javascript(render(partial: 'rating', locals: { item: #item })) %>');
This code works only if you've got jQuery installed, but it should be easily translatable to Prototype or whatever JS framework you may be using.
And the partial for the rating, called _rating.html.erb, was something like:
<%= form_tag url_for(controller: 'items', action: 'rate', id: item.id), remote: true %>
<%= rating_stars(item.rating_score, item.ratings) %>
<%= item.ratings %> Votes
</form>
In this partial, the rating_stars() helper method generated some kind of star-like representation for the rating, but you can do that however you like.
By setting "remote: true" in the form_tag helper, your Rails installation should automatically transmit the request via the installed Javascript framework. This magic is part of the whole unobtrusive javascript thing going on in Rails lately, which is actually pretty cool.
Hope this gives you an idea of how to realize a very simple rating system with no IP lock feature whatsoever in Rails.
Looks like the Watir documentation rating system is set up through polldaddy.
For this particular case, it appears they include the polldaddy javascript which populates the rating div container with their star rating widget. Looks like there's a corresponding javascript object which you can inspect:
console.log( PDRTJS_101132_page_2.avg_rating ); //=> 4
If you had numerous rating widgets like these on a page, and you were able to make a collection of the javascript objects paired with their divs, presumably you could sort them based on that average rating property.

Resources