I have the following setup of models and controllers:
Models:
class Company < ActiveRecord::Base
has_many :follow_companies, dependent: :destroy
has_many :followers, through: :follow_companies, source: :user
end
#join table
class FollowCompany < ActiveRecord::Base
attr_accessible :company_id
belongs_to :user
belongs_to :company
end
class User < ActiveRecord::Base
#a user can follow many companies
has_many :follow_companies, dependent: :destroy
has_many :followed_companies, through: :follow_companies, source: :company
end
Controllers:
class FollowCompaniesController < ApplicationController
def create
company = Company.find params[:follow_company][:company_id]
current_user.follow_companies.create! company_id:company.id
redirect_to company
end
def destroy
company = Company.find params[:id]
current_user.follow_companies.find_by(company_id: company.id).destroy
redirect_to company
end
end
The join table as well as companies and users is a resource:
resources :users
resources :companies
resources :follow_companies, only: [:create, :destroy]
Now I'd like to have buttons in my frontend for users to UNfollow a company assuming, they already follow that company:
The following view is part of the Company show action and not the FollowCompany show action
View:
<%= follow_company = current_user.follow_companies.find_by_company_id(#company.id) %>
<%= form_for(follow_company, :html => { :method => :delete }) do |f| %>
<%= f.submit "Unfollow", class: "btn pull-right" %>
<% end %>
When browsing to companies/show however, I get an error in the form_for line above:
ActionController::RoutingError at /companies/10
No route matches {:action=>"destroy", :controller=>"follow_companies", :format=>nil, :id=>#<FollowCompany user_id: 2, company_id: 10, created_at: "2013-03-21 23:34:36", updated_at: "2013-03-21 23:34:36">}
Request parameters
{"action"=>"show", "controller"=>"companies", "id"=>"10"}
Why can't rails find the route?
Pretty sure you need to pull :method => :delete out of the html args:
<%= form_for(follow_company, :method => :delete) do |f| %>
Not sure if that's the only problem but that's what caught my eye.
Something like this seems a bit more elegant too (automagically creates a form):
= button_to "Unfollow", follow_company_path(follow_company), :method => 'delete'
An alternative way to achieve this without writing a form is below. If you want you can do this with a single link.
<%= link_to "Unfollow", follow_compony_path(follow_company), :method => :delete %>
Related
I have a Group model, which has many lists.
Group
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
has_many :lists
accepts_nested_attributes_for :lists
cattr_accessor :current_user
end
List
class List < ApplicationRecord
belongs_to :group
validates_presence_of :group_id
end
I iterate over #group.lists
<% #group.lists.each do |elem| %>
<p><strong><%= elem.title %></strong></p>
<p><%= elem.body %></p>
<%= link_to 'Delete list', [elem.group, elem], method: :delete,
data: {confirm: "Are you sure?"} %>
<%= link_to 'Update list', edit_group_list_path(:group_id => #group.id, :list_id => elem.id), method: :put %>
<% end %>
Delete method works good, but update method works wrong. Instead of creating links like http://localhost:3000/groups/9/lists/10/ where group_id is 9 and list_id is 10, it's doing something like this
http://localhost:3000/groups/9/lists/9/edit?list_id=15
Routes:
resources :groups do
resources :lists
end
Run
rails routes
to understand where you are wrong
Anyway, the nested resource requires just id, so
edit_group_list_path(:group_id => #group.id, :id => elem.id)
Any other parameter is added in query string
As #Ursus said, the default behavior of nested resources in rails to to accept a plain :id parameter for the innermost resource, /groups/:group_id/lists/:id. You can also simply pass in the objects directly instead of mapping to ID integers:
edit_group_list_path(#group, elem)
You can read more about nested resources here: http://guides.rubyonrails.org/routing.html#nested-resources
I am getting following error :
undefined method `recommendations_path' for #<#<Class:0x0078>>
I have Recommendation model
class Recommendation < ActiveRecord::Base
belongs_to :user
belongs_to :recommended_user, class_name: "User", foreign_key: :recommended_user_id
end
I have user model
class User < ActiveRecord::Base
has_many :recommendations
................
end
In recommendation controller
def new
#recommendation = current_user.recommendations.new
end
In new.html.erb
<%= form_for #recommendation do |f| %>
<%= f.text_field :relationship %>
<%= f.text_field :comment %>
<%= f.submit %>
<% end %>
My routes, where I think problem is:
devise_for :users
resources :users, only: [:show] do
collection do
get :customer_signup
get :employee_signup
end
member do
get :choose_role
get :become_a_customer
get :become_a_employee
end
end
resources :users do
resources :recommendations
end
Thats actually when the form is trying to identify the path for your #recommendation.
According to your routes.rb your form must be:
<%= form_for [:user, #recommendation] do |f| %>
I am trying to build a simple learning app with rails 4.
here are my models:
class User < ActiveRecord::Base
has_many :enrollments
has_many :lectures, through: :enrollments
accepts_nested_attributes_for :enrollments
end
class Enrollment < ActiveRecord::Base
belongs_to :user
belongs_to :lecture
end
class Lecture < ActiveRecord::Base
has_many :enrollments
has_many :users, through: :enrollments
end
And here are my controllers
class EnrollmentsController < ApplicationController
before_action :authenticate_user!
def create
#enrollments = current_user.enrollments.build(enrollment_params)
if #enrollments.save
flash[:success] = "You have successfully enrolled."
redirect_to profile_path(current_user)
else
flash[:danger] = "Please try again."
redirect_to root_path
end
end
private
def enrollment_params
params.require(:enrollment).permit(:user_id, :lecture_id)
end
end
Here are my views:
lectures/index.html.erb
<% #lectures.each do |lecture| %>
<%= image_tag lecture.picture.url(:medium) %>
<p><%= truncate(lecture.description, length: 80) %> </p>
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments"}, :method => :post %>
<% end %>
The problem is that when you click on Enroll Now I have the following error:
ActionController::ParameterMissing in EnrollmentsController#create
param is missing or the value is empty: enrollment
def enrollment_params
params.require(:enrollment).permit(:user_id, :lecture_id)
end
How can i make it work? Need help please
In your lectures/index.html.erb file, you are not passing any data to the controller's action method.
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments"}, :method => :post %>
Might be better served with something a la
<%= link_to "Enroll Now", {:action=>"create", :controller=>"enrollments", :user_id => current_user.id**, :lecture_id => lecture.id}, :method => :post %>
# ** not sure how you snag the current user's id in your app but you'd need it.
Also, take a look at Routing in Rails. There are some super handy helper methods you can use that will allow you to do something like this (this was done quickly and may not be totally accurate but is offered to show you how you can use a route's path helper to clean up the code and make it even more readable):
<%= link_to 'Enroll Now', enrollments_path({enrollment: { user_id: current_user.id, lecture_id: lecture.id }}), :method => :post %>
I'm trying to create a simple Like/unlike button with Rails 4. I tried to do this with socialization gem, but after one day of struggling I gave up and decided to modify M. Hartl's 'foollow' mechanism from Rails Tutorial. Here is what i got so far:
User.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :validatable
has_many :questions
has_many :answers
has_many :likes, foreign_key: "liker_id", dependent: :destroy
has_many :liked_answers, through: :likes, source: :liked, source_type: "Answer"
def like?(answer)
likes.find_by(liked_id: answer.id)
end
def like!(answer)
likes.create!(liked_id: answer.id)
end
def unlike!(answer)
likes.find_by(liked_id: answer.id).destroy
end
end
Answer.rb:
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
has_many :likes, foreign_key: "liked_id",
class_name: "Like",
dependent: :destroy
has_many :likers, through: :likes, source: :liker
end
Like.rb:
class Like < ActiveRecord::Base
belongs_to :liker, class_name: "User"
belongs_to :liked, class_name: "Answer"
validates :liker_id, presence: true
validates :liked_id, presence: true
end
likes_controller.rb:
class LikesController < ApplicationController
skip_before_action :verify_authenticity_token
before_action :authenticate_user!
respond_to :html, :js
def create
#answer = Answer.find(params[:like][:liked_id])
current_user.like!(#answer)
respond_with #answer.question
end
def destroy
#answer = Like.find(params[:id]).liked
current_user.unlike!(#answer)
respond_with #answer.question
end
end
_like.html.erb:
<%= form_for(current_user.likes.build(liked_id: #answer.id), remote: true) do |f| %>
<div><%= f.hidden_field :liked_id %></div>
<%= f.submit "Like!", class: "btn btn-large btn-primary" %>
<% end %>
_unlike.html.erb:
<%= form_for(current_user.likes.find_by(liked_id: #answer.id),
html: { method: :delete }, remote: true) do |f| %>
<%= f.submit "Unlike.", class: "btn btn-large" %>
<% end %>
routes.rb:
Rails.application.routes.draw do
devise_for :users
scope "/admin" do
resources :users
end
resources :questions do
resources :answers do
get :likes
end
end
resources :likes, only: [:create, :destroy]
root to: 'questions#index'
end
I also have jQuery and jQuery_ujs required in application.js, and relevant js.erb files ("create" and "destroy") in views.
The 'like/unlike' mechanism itself seems to work pretty well - in the console, with my 'like!' and 'unlike!' methods, I'm able to create and destroy "Like" objets with id, liker_id and liked_id.
The problem begins with the button itself.
I can see the "Like!" button next to each answer, but when I click it - I get this error:
ActiveRecord::RecordNotFound in LikesController#create
Couldn't find Answer with 'id'=
The error points on this line in LikesController:
#answer = Answer.find(params[:like][:liked_id])
so I suppose my #answer.id results to be 'nil', but I have no idea where did I make mistake. My first guess would be routes file - I'm still not sure if everything is correct there.
I've spent whole day looking for solution, I also found some similar questions on SO, but none of the answers could help me.
Any ideas would be greatly appreciated.
EDIT: Params from the error
Parameters:
{"utf8"=>"✓",
"like"=>{"liked_id"=>""},
"commit"=>"Like!"}
You're using the hidden field tag wrong. http://api.rubyonrails.org/v4.1.1/classes/ActionView/Helpers/FormHelper.html#method-i-hidden_field shows you need to supply two values into your tag. Change your like ERB file to this:
_like.html.erb:
<%= form_for(current_user.likes.build(liked_id: #answer.id), remote: true) do |f| %>
<div><%= f.hidden_field :liked_id, :value => #answer.id %></div>
<%= f.submit "Like!", class: "btn btn-large btn-primary" %>
<% end %>
and that should get you what you want.
first i listed all the menu that the guest added inside the package that he also added i listed them with this
_menuadded.html.erb
<h1>menu you added</h1>
<% #reservation_package.package_line_items.each do |menu|%>
<p><%= link_to menu.menu.name, menu_reservation_reservation_package_reservation_package_pages_path(#reservation,#reservation_package,menu) %></p>
<p><%= link_to "delete item" ,reservation_package_package_line_item_path(#reservation_package,menu), :method => :delete%></p>
<%end%>
then i try to route to the next static page with this <p><%= link_to menu.menu.name, menu_reservation_reservation_package_reservation_package_pages_path(#reservation,#reservation_package,menu) %></p>
and the it produce this URL http://localhost:3000/reservations/10/reservation_packages/39/reservation_package_pages/menu.29
im just wondering if how can i catch the menu that he opened i mean how to catch this localhost:3000/reservations/10/reservation_packages/39/reservation_package_pages/menu.29
in my menu semi static page controller where this route to,i tried this
#reservation_package = ReservationPackage.find(params[:reservation_package_id])
#menu = Menu.find(params[:id])
but didn't work at all im just wondering if im doing it right or if im wrong can you give me a advice how to implement this kind of module? thanks more power
ROUTES:
resources :services
resources :reservations do
resources :pages do
collection do
get :functionroomlist
get :packagelist
get :package
# get :menu
end
end
resources :reservation_packages do
resources :reservation_package_pages do
collection do
get :menulist
get :menu
end
end
resources :package_line_items
end
resources :reservation_function_rooms
end
We had an similar issue I hope i can help you a little bit
my user can create an productlist and he can directly add new products on it. On the show-form i set an link like this
<%= link_to 'Create', new_product_path(:procuctlist => #productlist.id) %>
In the controller of products i definded the new-Action so
def new
#product_entry = ProductEntry.new
#product_entry.productlist_id = params[:productlist]
respond_to do |format|
format.html # new.html.erb
format.json { render json: #wishlist_entry }
end
end
The Models are defined so
class Product < ActiveRecord::Base
belongs_to :productlists
has_many :registrations, :dependent => :destroy
validates :entry_name, :description, :presence => true
end
class Productlist < ActiveRecord::Base
has_many :products, :dependent => :destroy
end
the table products contains the field productlist_id.
The view of products in our first alpha version contains the productlist_id.
<div class="field">
<%= f.label :productlist_id %><br />
<%= f.number_field :productlist_id %>
</div>
We hope we could help you.