I have two controllers Businesses and Specials. They both have a tables one Business and one Special. They are relational. The controller Specials has a column called business_id which is connected to the database Business and that id. Im trying to make it so when you click on the link on the Specials controller index view the link to the business it goes to the Businesses controller show view so the link is Business/nameofbusiness
--- Businesses Controller ---
class BusinessesController < ApplicationController
def show
#business = Business.find(params[:id])
end
end
--- Business Model ---
class Business < ActiveRecord::Base
has_many :specials
end
-- Specials Controller
class SpecialsController < ApplicationController
def index
#specials = Special.all
end
def show
#special = Special.find(params[:business])
end
end
-- Special Model ---
class Special < ActiveRecord::Base
belongs_to :business
end
--- Index View of Specials Controller --
<h1> Specials </h1>
<% #specials.each do |special| %>
<hr />
<h4> <%= link_to special.name, special %> </h1>
<h6> <%= link_to special.business.business_name, business_path(#special) %> </h6>
<p> <%= special.description %> </p>
<hr />
<% end %>
You'll have to create a new route for that, since business_path will be converted to something like businesses/:id, so in your config/routes.rb you can add:
get "/businesses/:business_name" => "businesses#show", :as => :business_show
and of course on your controller you can't do a plain find anymore, so instead you can use something like this:
#business = Business.find_by_name(params[:business_name])
NOTE: here you would be having two routes with different params going to the same action (the business_path will continue to send requests with params[:id] to the show action) and there will be issues due to that, so you can do two things:
If you're not going to use the default show route anymore (eg: businesses/:id), you can add this to your routes file:
resources :businesses, except: :show
Create a separate action for handling that kind of request, so instead of using show, use show_business for example.
get "/businesses/:business_name" => "businesses#show_business", :as => :business_show
The link_to helper makes this super easy. Use it this way.
<h6> <%= link_to special.business.business_name, special.business %> </h6>
If you want the name of the business in path you need to do more. The gem FriendlyId was made for this. Here's a great (free) railscast on how to use it.
Related
I've an issue with the paths in the views and I don't know how to solve it.
I've "categories" that has_many "posts" and "posts" that belongs_to "categories".
1.- I want to show on home page the truncate last post of an specific category (the ID number "1"). Then I want that post to link to the show post path but I get this error:
"Unknow Action
The action 'index' could not be found for PostsController"
I think I've my paths wrong because I don't need the index view because I'm only going to show that specific post. So, I think that category_posts_path(#last_post) is not the right path (I don't know where to look for more info about making the route path in the views...). Actually, the browser is showing me that is looking for the "2" category when it is a post of the "1" category...? What am I doing wrong?
This is the browser route:
http://localhost:3000/en/categories/2/posts
This is my views/categories/home.html.erb file:
<div class="post_details">
<h2><%= #last_post.title %></h2>
<%= image_tag #last_post.image(:header), class: "post_image" %>
<p><%= truncate #last_post.body, length: 100 %></p>
<p class="button"><%= link_to "READ MORE", category_posts_path(#last_post) %></p>
</div>
2.- I have another path problem in the views/categories/show.html.erb file. I have a loop to show all the post of one specific category, but when I link in some post (to show it) there is the "index" error again:
"Unknow action
The action 'index' could not be found for PostsController"
This is the browser route:
http://localhost:3000/en/categories/1/posts
This is the views/categories/show.html.erb file:
<div class="post_details">
<h2><%= link_to post.title, category_posts_path(post) %></h2>
<%= image_tag post.image(:header), class: "post_image" %>
<p><%= post.body %></p>
</div>
This is the categories_controller.rb file:
class CategoriesController < ApplicationController
before_action :get_categories
def index
end
def show
#category = Category.find(params[:id])
end
def home
if params[:set_locale]
redirect_to root_url(locale: params[:set_locale])
else
#category = Category.find_by_id(1)
#last_post = #category.posts.order("created_at desc").first
end
end
def get_categories
#categories = Category.all.order("rank asc, name asc")
end
end
This is my posts_controller.rb file:
class PostsController < ApplicationController
def show
#category = Category.find(params[:category_id])
#post = #category.posts.find(params[:id])
end
end
This is my route.rb file:
scope '(:locale)' do
resources :categories do
resources :posts
end
resources :contacts
root 'categories#home'
get "/contact" => "contacts#new"
# static pages
get "/investment" => "contents#investment"
get "/partner-with-us" => "contents#partner", as: "partner"
get "/our-companies" => "contents#companies", as: "companies"
get "/site-map" => "contents#sitemap", as: "sitemap"
get "/terms-and-conditions" => "contents#terms", as: "terms"
get "/privacy" => "contents#privacy"
end
When you are nesting routes you should always consider what is the parent and whats a child in given route. Since your paths don't know anything about your associations you have to explicitly define every object in the nesting.
I.e. since you nested posts in categories linking to last post in given category would look like this:
category_post_path(#category, #last_post)
(I think you have also a typo there - category_posts_paths - which links to posts index index - hence the error. Use category_post_path. instead, and give it both parent category and the post.
You can run rake routes to see exact information on paths (or go to http://localhost:3000/rails/info/routes )
I am trying to figure out the proper restful way of displaying all posts from all users.
I have an application with a user and post resource. The post resource is nested in the users. Now I am trying to sort of display a feed of all posts and with the name of the user who posted them.
I cant quite figure out where this feed should be placed. And in view file, how to get post user names.
in controller:
#posts = Post.all(:include => "user")
in view:
<% #posts.each do |post| %>
...
some html here
...
<%= post.user.name %>
<% end %>
Pay attention to "include" word. It means that users information will be got with posts with 1 query to Database.
To better understand it you can read this
You can create a route for displaying all posts by:
routes.rb
get "posts" => "posts#index"
This will create a route http://yourdomain.com/posts that will show all posts. Then make sure you have an action for index to show all of the posts.
posts_controller.rb
class PostsController < ApplicationController
def index
#posts = Post.all(:include => "user")
end
end
Make sure your model associations are set up properly.
user.rb
has_many :posts
post.rb
belongs_to :user
# This assumes you have a column on your table for user_id which I assume you do since you mentioned your nested resource already.
You view would simply show the user's name associated with each post.
views/posts/index.rb
<% #posts.each do |post| %>
post.user.name
<% end %>
I am trying to create a simple micropost application using rails...
This is my model :
Class Micropost < ActiveRecord::Base
attr_accessible :content, :name
end
Controller:
class MicropostsController < ApplicationController
def create
#blog=Micropost.new( :content => params[:content])
#blog.save
redirect_to microposts_show_path
end
def show
#mblg=Micropost
end
def index
end
end
Views:
create.html.erb
<h1>Microblogs#create</h1>
<p></p>
<%= label_tag(:content) %><br/>
<%= text_field_tag (:content) %><br/>
<%= submit_tag("submit") %><br/>
index.html.erb
<h1>Microblogs#index</h1>
<p>Find me in app/views/microblogs/index.html.erb</p>
show.html.erb
<h1>Microblogs#show</h1>
<p></p>
<%= #mblg.each.do |variable|%>
<p><%= variable.content %></p>
<%end%>
Routes.rb
Blog::Application.routes.draw do
get "microposts/create"
get "microposts/show"
get "microposts/index"
end
i am getting a template missing error... this is a fairly simple application...can you please point out where i am going wrong?
The RESTful controller in Rails has hidden actions (create, update, destroy)
The controller (if created as part of the scaffold) will have four actions visible to the user
index
new
show
edit
In our routes file, you can call
resources :microposts
which Rails will understand and create the routes for a RESTful controller.
Instead of /microposts/create you would use /microposts/new
A good example you can look at is a scaffold.
Within your Rails root directory, do the following
rails g scaffold foo bar
rake db:migrate
You will see that this creates a Foo controller and allows you to new/index/edit/show on this controller. The field that you would be entering and populating is bar.
Once you are finished playing around with this, you can do
rails d scaffold foo
rake db:rollback
I'm trying to get a link on an articles show page so that when a user clicks write new review it takes them to the link
/comic_reviews/'the article they want to comment on'/reviews/new
where they will be directed to the new reviews page
how can i accomplish this with
In your routes file you would specify a route like this
match '/comic_reviews/:comic_name/reviews/new' => 'reviews#new', via: :get
Then in your reviews controller you would need something like this
reviews_controller.rb
class ReviewsController < ApplicationController
def new
#comic = Commic.find_by_name(params[:comic_name])
if #comic
#review = #comic.reviews.build
render 'new'
else
#Render some error page since comic was not found
end
end
end
You will then have access to #comic and #review in your reviews/new view so you could build a form that just makes a post to create a review and allows you to store it. This should get you going.
Edit
In your new view you'd need to have a form that looks something like this
<%= form_for #review do |f| %>
<%= f.label :some_attribute %>:
<%= f.text_field :some_attribute %><br />
<%= f.submit %>
<% end %>
This will be expecting you have a route to create a review in your routes file and an action in your ReviewsController.
If you are struggling with such topics I suggest you read over this excellent tutorial
http://ruby.railstutorial.org/ruby-on-rails-tutorial-book
Or just read through the documentation for Rails API which will give you pretty accurate examples.
You can do this via routes
resources :comic_reviews do
resources :reviews
#probably_some_other_route_here
end
And with restful pattern it will be easy to achieve whatever you want
controller
Someclass < Someotherclass
#some your code
def new
#instance_var = Your_model.new
end
def create
#instance_var = Your_model.new(params[:some_name_here])
if #instance_var.save
redirect_to somewhere
else
render 'new'
end
end
end
Also you'll need form, but i dont think that will cause any troubles
I am new in Rails. And I have a project that;
I should get a value from user in View page (for example index), and I should use the value in Helper then send the result of Helper to Controller and show the result in a new View page (for example details). Additionally I have to save results to database. Right now I have helper, controller and view pages but I can't connect these three part to each other. I need help
Controller;
def index
#user = Mpeople.new[:user]
redirect_to "secondstep"
end
def secondstep
# helper should have controled here
redirect_to "following"
end
def following
#user = Mpeople.all
end
Model;
class Mpeople < ActiveRecord::Base
has_one :username
accepts_nested_attributes_for :username
end
View;
<% form_for :user, :url => {:action => "index"} do |pform| %>
<% pform.fields_for :person do |namefield| %>
Twitter Name : <%= namefield.text_field :username %>
<%= button_to "OK", :action => "following" %>
<% end %>
<% end %>
And helper is more longer, it sends twitter name to twitter and get following of a user from api.twitter.com
This is some of my helper; I edit it after your comment but I am not sure if it is correct or not.
module FafHelper
class PeopleController
require 'people_helper'
# txtname = indexteki textbox'un adına eşitle
#txtname = tname
txtname = namefiled.text_field
.....
a_get("1/users/lookup.#{json}").
with(:query => {:screen_name => txtname, :user_id => id_list}).
end
end
..
You no need to connect views and helper as by default all the helper modules are included in the views.
And do include the helper in you controller. Helper is a module and controller is a class. Just include the module in the class.
To get the clear picture please post exactly your structure.