how to use click event in rails 4 - ruby-on-rails

My code:
<%#categories.each_with_index do |d,index| %>
<%= link_to d.name ,{:action=>'index',:id=>d.id,:hotel_id=>d.hotel_id},class: "btn-orange" %>
<%end%>
In my Controller:
def index
#category = Category.where(:hotel_id => params[:hotel_id]).first
#menus2=Menu.where(:category_id=> #category.id).sorted
#categories=Category.where(:hotel_id=>params[:hotel_id])
#cart = current_cart
if params[:name]==params[:name]
#menus=Menu.where(:category_id=> params[:id]).sorted
else
end
end
I am new in rails.I want to use #menus2=Menu.where(:category_id=> 0).sorted this code when link_to is clicked.How can i do in my controller, is there any click event in ROR.

You can add a remote attribute to your link_to method:
= link_to d.name, controller_index_path, class: 'btn etc', remote: true
This will allow Rails to make an 'Ajax' call to your desired controller.
Note: when making a remote call such as this, Rails will receive/respond via .js. This means that you need to have an index.js.erb file that does what you need and reports back to the 'Ajax' caller whatever data is necessary.
This page in the Rails guide may help with additional details, etc.: Working with JavaScript in Rails

Related

Rails View isn't refreshing after redirect_to

I'm working on a sample Rails app that has Users, Events (that the user creates) and ultimately, Users will be able to subscribe / attend these events.
I have a table where users can subscribe and unsubscribe from events when they click a link_to button in the event row. The link_to calls a method from the event_controller that has a redirect to the current_path but when I click the button nothing happens to the view but it appears that the server renders the view.
Is this because I am calling it from the event_controller but using the show controller from User ?
LOG:
Rendered users/show.html.erb within layouts/application (17.1ms)
Users > show.html.erb
<% if current_user?(#user) %>
<td><%= link_to "Delete", e, method: :delete,
data: { confirm: "You sure?" } %></td>
<% else %>
<% if attendingEvent?(current_user, e.id) %>
<td><%= link_to "Not Going", events_remove_event_to_attend_path(event_id: e.id, event_owner_id:#user.id, current_path:request.fullpath), remote: true %></td>
<% else %>
<td><%= link_to "I Want To Go", events_add_event_to_attend_path(event_id: e.id, event_owner_id:#user.id, current_path:request.fullpath), remote: true %></td>
<% end %>
<% end %>
events_controller.rb
def add_event_to_attend
puts attend_params
puts request.fullpath
#attend = Attendee.new
#attend.event_id = (attend_params[:event_id])
#attend.user_id = current_user.id
if #attend.save
flash[:success] = "You created an assocations"
redirect_to(attend_params[:current_path])
puts 'saved'
else
flash[:danger] = "You did not create the event"
puts 'not saved'
end
end
def remove_event_to_attend
#event_to_delete = Attendee.find_by_user_id_and_event_id(current_user.id,params[:event_id])
#event_to_delete.destroy
redirect_to(attend_params[:current_path])
end
Hi and welcome to Stack Overflow.
So firstly... I notice you've put some putses in your code... what do you see in the server logs/terminal screen?
Secondly: what do you have in your rjs templates? you do have rjs templates right? You've made the links remote - which means you're sending a js request and the browser will only change its view if you send it back some js that tells it to do so.
Alternatively, you can fix this quite quickly by removing remote: true from the links, and then the redirection will Just Work... because it's no longer a js-request and just an ordinary request.
I'm new in Ruby on Rails too.
I'd like to add something to Taryn's answer. Maybe if you use redirect_back fallback_location: asd_path, asd_path being the name of the path of the same page (not for the same action), it could work.
I hope this helps, and welcome to Rails! I'm a newbie too, but rails is easy to learn! And I <3 Ruby, love at first sight.
Quick note: I'm using Rails 5, so if you're not using the same it may not work. Check in Rails docs (Be sure to check the same version you're using)

How to add checkbox values (client ids) to a User attribute (User.clients)

I've been struggling to get this to work following a tutorial. I've got Users that have profiles, and a Client model that, through a 'many to many' join table, establishes the relationships between the user and the clients.
What I'm trying to do is create a list of check boxes generated from the list of clients in the DB that you can tick on or off, and then when you submit it, the user will have the relationship to those clients through the join table.
It's sort of working with static data as you can see below:
/profiles/show.html.erb
<% #clients.all.each do |client| %>
<li>
<%= check_box_tag "user[client_ids][]", client.id %>
<%= client.client_name %>
</li>
<% end %>
<%= link_to 'Add Clients', '../assign_clients/' + #profile.user.id.to_s , class: 'btn btn-default' %>
Routes
get 'assign_clients/:id', to: 'users#assign_clients'
And finally in my users_controller.erb
def assign_clients
#user = User.find(params[:id])
#user.client_ids = [1,2]
redirect_to :back, alert: 'Assigned Users'
end
Obviously it's just using hard coded values of 1 and 2. What I'm not sure how to do is wrap the checkboxes in the correct form tag/simple_form (which I am using), and then with the 'submit' button, have that do the 'assign_clients' action that passes through the values.
Thank you for any help.
What I'm not sure how to do is wrap the checkboxes in the correct form
tag/simple_form (which I am using), and then with the 'submit' button,
have that do the 'assign_clients' action that passes through the
values.
In order to create a form that will trigger the assign_clients method a route needs to be setup in your routes.rb file like the following:
resources :users do
patch 'assign_clients', to: 'users#assign_clients', as: 'assign_clients'
end
This sets up a route for a user that you can use the http patch method with (ie. UPDATE). The plan is to pass the client_ids to the users controller as params from the form. I gave it a path name so that we can reference it in the form as user_assign_clients_path(:user_id)
Now that we have the route set up...using the default rails form tags you can structure the form along the lines of this:
<%= form_for #user, url: user_assign_clients_path(#user) do |f| %>
<% #clients.each do |client| %>
<li>
<%= check_box_tag "user[client_ids][]", client.id, #user.clients.include?(client) %>
<%= client.client_name %>
</li>
<% end %>
<%= f.submit "Add Clients", class: "btn btn-default" %>
<% end %>
This will create a form allowing you to post the selected clients as an array of ids to the assign_clients method.
Finally, the assign_clients method can then retrieve the client_ids from the params hash (via params[:user][:client_ids] most likely) and update the user instance (retrieved using user_id from params hash also). You will probably have to add client_ids: [] to the end of your strong parameters list for user to whitelist it - but this essentially should behave like a typical update method.
def assign_clients
#user = User.find(params[:user_id])
#user.update(user_params)
redirect_to wherever_path
end
def user_params
params.require(:user).permit(
client_ids: []
)
end
You need to understand several basic concepts, let me explain to you:
on: member routing - in order to solve your issue directly, your route should be something like:
resources :users do
post '/assign_clients/:client_id', on: :member
end
so that other than user_id, the :client_id can be also passed in as a parameter. For the details, you can read about rails guides on routing.
For the checkbox way, you need nested_attributes - http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html. So that you can achieve what u need with a simple update call on users.
You can also implement a customised logic, with the client_ids passed in as parameters. In order to learn how forms & parameters work in rails, you can build a form, submit it, and see how it goes in the rails server log.
If anything is unclear, simply comment below & I'll try to update.

Destroying multiple records using select tag

I am trying to allow users to select multiple records to destroy in my rails 3 app.
I have a check_box_tag in my products index as follows:
<td><%= check_box_tag "product_ids_destroy[]", product.id %></td>
And added a submit tag in my index:
<%= submit_tag "Delete Selected" %>
And in my products controller I created a method:
def destroy_select
product_ids = params["product_ids_destroy"]
objs = Product.find(:all, :conditions => ["products.id IN (?)", product_ids])
objs.each { |o| o.destroy}
end
And defined my routes.rb:
resources :products do
collection do
delete 'destroy_select'
end
The method works in console. How do I "connect" the product_ids I collect from my index to the controller method to destroy each record? Can I add the method as an option in the submit tag? Also, if I wanted to add a confirm before destroy, do I add this to my submit tag?
check your routes using
bundle exec rake routes
then on your form you can set the action of the form to that named route and the method to delete
you can do a tiny refactor of your controller's action
def destroy_select
Product.destroy_all(params["product_ids_destroy"]) unless params["product_ids_destroy"].blank?
end
To hook that form submission into the right action in your controller, you're going to have to make the form use the DELETE method. That option (:method => :delete) has to be set in your form_for or form_tag function call.
You can hook your confirmation message onto the submit_tag itself, though. Check out the :confirm => 'My message?' option in the docs.
Hope that helps!

how to connect my model to my app

Hey all,(im a beginner in rails)
i've created a controller that look like that:
class HomeController < ApplicationController
def homepage
end
def showmsg
#postword = params[:p]
end
end
the showmsg view looks like that:
<%= #postword %>
and my homepage view looks like that:
<%= form_tag( {:controller => 'home', :action => 'showmsg'}, :method => "post") do %>
<%= text_field_tag(:p,#postword) %>
<%= submit_tag("post") %>
<% end %>
now i have a form that i can write something in it and it will show on the showmsg view.
i created a model with the param :posts with a :description "text" field too.
MY QUESTION is how do i implement the model in the code so any thing i write will be in a list with the things i wrote before, because now (obviously) anything if i write something its deleting the one i wrote before.
thank you all!
I would argue that you're approach is not very rail's like... so if you're learning rails... you're learning it wrong.
Make a Model. Call it "Message":
rails generate model Message content:string
remember to migrate (hopefully you have your databases setup properly):
rake db:migrate
Then in your controller, when you post, you can create message like this:
def create #instead of showmsg... 'create' is the standard name for this
Message.create(params[:message])
#messages = Message.all
end
This will create the message in the database, and then it will get all the messages out of the database and put them into #messages.
You need to edit your form so that it uses form_for. You need to pass it #message, which is an instance of Message.new that your first controller action created. You should call this new
In your create.erb.html file, you show all the messages like this:
<ul>
<% #messages.each do |message| %>
<li><%= message.content %></li>
<% end %>
</ul>
I actually wouldn't recommend showing all the messages in the create action - it should really happen in the index action and you should redirect... but we need to keep this simple. Just google this or watch some of Ryan's screencasts and you'll get it.
And you're done. This is the "Rails Way" to do things. It's best to learn it the way they want you to learn it.
I would also commend that you format your code properly by indenting, and start naming your methods to be real english. For example, showmsg is bad and show_message is a lot better.
If all of this is totally confusing, then just create a new project, and then type:
rails generate scaffold message content:string
It will basically build the application you want and a lot more. You can just read the code and see how they did it.
Hope it helps.
Your approach is not really rails like so some tweaks and fixes are needed. Suggestions: check rails approach to REST. The following code will work it is a little more rails like, but still not all the way there.
Generate a model
rails generate model Message postword:string
this will generate the model and create the migration necessary to create the table in the database.
Create the table
rake db:migrate
Define a post action
It will save the postword in the database. In your controller:
def create
#message = Message.create!(params[:message])
if #message.save
redirect_to "/home/showmsg"
else
render :action => "/home/homepage"
end
end
Create and instance of Message to use in your form
def homepage
#message = Message.new
end
Fix your form tag
<%= form_for #message, :url => "/home/create" do |f| %>
<%= f.label :postword %>
<%= f.text_field :postword %>
<%= f.submit "Create" %>
<% end %>
Now let's show the words in the showmsg page
In the controller select the postwords from the database:
def showmsg
#postwords = Message.all
end
Showing them: /showmsg.html.erb
<H1>postwords list</H1>
<ul>
<% #postwords.each do |p| %>
<li><%= p.postword %></li>
<% end %>
</ul>
Your routes.rb file will have this routes:
get "home/homepage"
get "home/showmsg"
post "home/create"
Define an attribute :new_text in a way similar to this:
class TheModel
# Virtual writer - everything assigned to this attribute
# will be added to self.text
#
def new_text=(v)
self.text += v.to_s
end
def new_text
"" # This is write-only attribute
end
end
Now, use the field 'new_text' in your form.
Of course, this is a very simple example. You should decide whether you want to add the content on every call to :new_text=, maybe some validation would help, the read accessor may need some care, and so on.
For some good guides which may help you start, see the site http://guides.rubyonrails.org/

link_to problem

I want to display product count in a link_to, the link_to is a part of partial displayed in application.erb.html, the problem is, I have a method in my application controller named products_on_cart which return products count, when I try this code:
<%= link_to "<%= products_on_cart%>", :controller=>"carts", :action=>"index"%>
rails give me an error:
"syntax error, unexpected '>'
...er=>"carts", :action=>"index"%>"
I don't really understand why, can somebody help me?
You can't use <%= .. %> inside of <%= .. %>.
<%= link_to products_on_cart, [:carts] %>
You're nesting ERb tags. Make sure products_on_cart() is available as a helper method, then rewrite your link_to code without nested ERb tags as follows:
<%= link_to products_on_cart(), :controller => "carts", :action => "index" %>
To make products_on_cart() a helper method, either move it to app/helpers/application.rb, or declare it as a helper in your controller:
def products_on_cart()
# method definition goes here
end
helper_method :products_on_cart
If you only need to access products_on_cart from your views and not from your controllers, putting it in app/helpers/application.rb is the preferred way to go. If you need to use it in both controllers and views, use the helper_method approach above instead.

Resources