Can you please tell me how to display the list of orders of the company when moving from the general list of companies directly to its profile? Output here: views/companies/show.html.erb
Do not judge strictly, I'm just rolling into RoR. Thanks for understanding :)
Working request example with company id=305:
select o.id
from orders as o
inner join users as u ON o.user_id = u.id
inner join companies as c on c.id = u.company_id
where c.id = 305
models/user.rb:
class User < ApplicationRecord
belongs_to :company
has_many :orders
end
models/order.rb
class Order < ApplicationRecord
belongs_to :user
end
models/company.rb:
class Company < ApplicationRecord
has_many :users
end
users_controller.rb:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def index
#users = User.paginate(page: params[:page])
end
end
orders_controller.rb:
class OrdersController < ApplicationController
def show
#orders = Order.find(params[:id])
end
def index
#orders = Order.paginate(page: params[:page])
end
end
companies_controller.rb
class CompaniesController < ApplicationController
def show
#company = Company.find(params[:id])
end
def index
#companies = Company.paginate(page: params[:page])
end
end
views/companies/index.html.erb:
<!DOCTYPE html>
<html>
<%= will_paginate %>
<h1>Company list</h1>
<ul class='companies'>
<% #companies.each do |company| %>
<li>
<%= link_to company.full_name, company %>
</li>
<% end %>
</ul>
<%= will_paginate %>
<html>
views/companies/show.html.erb:
<!DOCTYPE html>
<html>
<div>id: <%= #company.id %></div>
<div>Register date: <%= #company.created_at %></div>
<div>Name: <%= #company.full_name %></div>
<html>
Works in console
orders = Order.joins(user: :company).where(companies: { id: 305 })
First add the missing definition of the association between companies and orders, like this:
# in app/models/company.rb
has_many :users
has_many :orders, through: :users
Then can just call #company.orders to get the list of orders associated with #company.
For example, in your views/companies/show.html.erb like this:
<!DOCTYPE html>
<html>
<div>id: <%= #company.id %></div>
<div>Register date: <%= #company.created_at %></div>
<div>Name: <%= #company.full_name %></div>
<ul>
<% #company.orders.each do |order| %>
<li>order <%= link_to(order.id, order) %></li>
<% end %>
</ul>
<html>
For example another way, its working:
Add to companies controller #orders:
def show
#company = Company.find(params[:id])
#orders = Order.joins(user: :company).where(companies: { id: params[:id] })
end
Add code to show.html.erb:
<div>
Order list of company:
<% #orders.each do |order| %>
<li>
<%= link_to order.id, order %>
</li>
<% end %>
</div>
Related
First of all I have this:
https://polar-scrubland-30279.herokuapp.com/ - my project which is deployed on heroku (Captain Obvious)
I've got projects and todos inside them.
For this moment I show all projects using this way:
------index.html.erb------
<%= render #projects %>
------_project.html.erb-----
<div class="project">
<div class="project-header">
<h2><%= project.title %></h2>
</div>
<div class="project-todos">
<% project.todos.all.each do |todo| %>
<p><%= check_box('tag', todo.__id__, {class: 'icheckbox_square-blue', checked: todo.isCompleted}) %> <%= content_tag :todotext, todo.text %></p>
<% end %>
</div>
</div>
And as you understand it doesn't allow me to change my todo's status when checkbox is checked. So that's why I need a form that will allow me to track all the checkboxes. Also I wanna make text-decoration: line-through when checkbox is pressed, but don't get how to.
Is there a way to creat a form which will satisfy my needs? Please can you help me, Any information will be appreciated.
ADDITIONAL INFORAMTION:
GitHub - https://github.com/NanoBreaker/taskmanager
project.rb
class Project < ActiveRecord::Base
has_many :todos
end
todo.rb
class Todo < ActiveRecord::Base
belongs_to :project
end
Lets start with the models:
class Project < ApplicationRecord
has_many :todos
accepts_nested_attributes_for :todos
end
class Todo < ApplicationRecord
belongs_to :project
end
accepts_nested_attributes_for lets you create or modify several nested Todo records at once when creating or updating a Project.
# will update 2 todos at once
#project.update(
todos_attributes: [ { id: 1, isComplete: true }, { id: 2, isComplete: false }]
)
We can use fields_for to create nested inputs for todos:
<%= f.form_for(#project) do |f| %>
<%= f.fields_for(:todos) do |tf| %>
<%= tf.check_box :isCompleted %>
<% end %>
<% end %>
This generates fields for todos nested under the key todos_attributes. We can whitelist them by using a hash key containing a array of permitted attributes.
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
def new
#project = Project.new
# this seeds the project with 3 empty tasks
# otherwise we don't have any inputs.
3.times { #project.todos.new }
end
def create
#project = Project.new(project_params)
if #project.save
# ...
else
# ...
end
end
def update
if #project.update(project_params)
# ...
else
# ...
end
end
private
def set_project
#project = Project.find(params[:id])
end
def project_params
params.require(:project)
.permit(:foo, :bar,
todos_attributes: [:isCompleted, :text]
)
end
end
You can create a form for each project by creating a partial which uses a local instead of an instance variable:
# app/views/projects/_form.html.erb
<%= f.form_for(local_assigns[:project] || #project) do |f| %>
<%= f.fields_for(:todos) do |tf| %>
<%= tf.check_box :isCompleted %>
<% end %>
<% end %>
# app/views/projects/index.html.erb
<% #projects.each do |project| %>
<%= render partial: 'projects/form', project: project %>
<% end %>
You can reuse the same partial for the other views as well:
# app/views/projects/new.html.erb
<%= render partial: 'projects/form' %>
# app/views/projects/edit.html.erb
<%= render partial: 'projects/form' %>
My project has three main parts to it:
Pages (similar to articles)
Categories (the pages have a category associated with them)
Tags (each Page can have several different tags)
I have a sidebar which uses #categories to pull through a list of all the current categories in my project:
<div class="col-md-3">
<p class="lead">Categories</p>
<div class="list-group">
<%= link_to 'All articles', pages_path(#page), :class => 'list-group-item' %>
<% #categories.each do |category| %>
<%= link_to category.name, category_path(category), :class => 'list-group-item' %>
<% end %>
</div>
</div>
But currently I need to include
#categories = Category.all
In my index and show actions in my controllers for both pages and categories so that the sidebar loads (I only use the sidebar in these two parts of the project).
Is there an easier way of doing this than including the above code in every action in the controller?
Also with the tags controller after creating a page and going to the tag's show page to view any pages associated with those tags, I get an error saying 'Couldn't find page with 'id'=2.
class TagsController < ApplicationController
def index
#tags = Tag.all
end
def show
#tag = Tag.find(params[:id])
#page = Page.find(params[:id])
#categories = Category.all
end
-
<% #tag.pages.each do |page| %>
<div class="thumbnail">
<div class="text">
<article class="clearfix">
<%= link_to page.title, url_for_page(page), class: "h1" %>
<p class="pull-right"><span class="glyphicon glyphicon-time"></span> Posted on <%= page.created_at.to_formatted_s :long %></p>
<hr />
<%= page.body.html_safe %>
<hr />
<div class="btn-group btn-group-xs" role="group" aria-label="...">
<% page.tags.each do |tag| %>
<%= link_to tag.name, tag_path(tag), class: "btn btn-info" %>
<% end %>
</div>
</article>
</div>
</div>
<% end %>
Anyone got any ideas? Any help would be greatly appreciated :)
Thanks!
Update:
Routes file:
Rails.application.routes.draw do
resources :categories
resources :pages
resources :tags
Models:
Category.rb
class Category < ActiveRecord::Base
has_many :pages
Page.rb
class Page < ActiveRecord::Base
include Bootsy::Container
belongs_to :category
has_many :taggings
has_many :tags, through: :taggings
def tag_list
self.tags.collect do |tag|
tag.name
end.join(", ")
end
def tag_list=(tags_string)
tag_names = tags_string.split(", ").collect{ |s| s.strip.downcase }.uniq
new_or_found_tags = tag_names.collect { |name| Tag.find_or_create_by(name: name) }
self.tags = new_or_found_tags
end
end
Tag.rb
class Tag < ActiveRecord::Base
include Bootsy::Container
has_many :taggings
has_many :pages, through: :taggings
def to_s
name
end
end
Tagging.rb
class Tagging < ActiveRecord::Base
include Bootsy::Container
belongs_to :tag
belongs_to :page
end
You could add a before_action for the controller limited to only index and show actions, as below:
class TagsController < ApplicationController
before_action :load_categories, only: [:index, :show]
# Your code
private
def load_categories
#categories = Category.all
end
end
That will load the categories into the instance variable for both the index and show actions.
For the error you're getting, if I'm reading it right you have nested routes? You need to be getting the correct ID for the tag, which is :tag_id:
def show
#tag = Tag.find(params[:tag_id])
#page = Page.find(params[:id])
#categories = Category.all
end
You were getting :id for both. If that doesn't work, are your routes nested? If not post your routes and I'll update the answer.
You can DRY out your Controller to set page and categories in a callback. But take care: you may omit the categories query in the categories#index action, but your page#... actions may skip the callback at all skip_before_action set_page or better overwrite the method and use a correct handling.
class ApplicationController
before_action set_page, only: [:index, :show]
before_action set_categories, only: [:index, :show]
private
def set_page
#page = Page.find params[:page_id]
end
def set_categories
#categories = Category.all
end
end
I have three models, Subscription, Show, and Episode. Subscription's role is to parse the feed in its :url column and instantiate Show and Episode, filling their columns with Feedjira properties.
I'm only able to access the episodes when I go to shows/1/episodes/1, using <%= render #show.episodes %> in the Shows show view doesn't work and doesn't give any errors.
In the Rails getting started guide, they used this as their Comment create method, which allowed for that.
#article = Article.find(params[:article_id])
#comment = #article.comments.create(comment_params)
redirect_to article_path(#article)
Is it the lack of params that's causing this? If so, how would I use params in this method?
def create
#subscription = Subscription.new(subscription_params)
if #subscription.save
#show = Show.new
#episodes = []
# Feed
#feed = Feedjira::Feed.fetch_and_parse #subscription.url
# Show
#show.title = #feed.title
#show.description = #feed.description
#show.genre = #feed.itunes_categories
#show.url = #feed.url
#show.logo = #feed.itunes_image
#show.save
# Episode
#feed.entries.each do |item|
#episodes.push(item)
end
#episodes.each do |item|
#episode = #show.episodes.create
#episode.title = item.title
#episode.description = item.summary
#episode.release_date = item.published
#episode.show_id = #show
#episode.save
end
redirect_to #subscription
end
end
episodes/_episode.hmtl.erb
<ul>
<li>
<%= episode.title %>
</li>
<li>
<%= episode.description %>
</li>
<li>
<%= episode.url %>
</li>
<li>
<%= episode.release_date %>
</li>
<li>
<%= episode.show_id %>
</li>
</ul>
shows/show.html.erb
<h1>Showing Show</h1>
<h2><%= #show.title %></h2>
<%= render #show.episodes %>
Adding my routes and models in case that's the issue:
routes.rb
Rails.application.routes.draw do
resources :shows do
resources :episodes
end
resources :subscriptions
root 'subscriptions#index'
end
show.rb
class Show < ActiveRecord::Base
has_many :episodes, dependent: :destroy
end
episode.rb
class Episode < ActiveRecord::Base
belongs_to :show
end
subscription.rb
class Subscription < ActiveRecord::Base
validates :url, uniqueness: true
end
Seems you need to just change
<%= render #show.episodes %>
to
<%= render partial: "episodes/episode", collection: #show.episodes %>
http://guides.rubyonrails.org/action_view_overview.html#partials
And small advice: don't place your logic in controller.
I'm trying tu use Single Table inheritance to represent that employees can be managers or consultants.
So here's my employees model:
class Employee < ActiveRecord::Base
belongs_to :communaute
self.inheritance_column = :fonction
scope :manager, -> { where(fonction: 'Manager') }
scope :consultant, -> { where(fonction: 'Consultant') }
end
and here are my subclasses :
class Consultant < Employee
end
class Manager < Employee
end
When i'm oppening the new view to create an employee. I have undefined method `fonction' error when i'm trying to list the types on employees.
I don't understand why because i defined it in the employee controller.
Could you please help me on this error please.
Below my new form
<%= form_for(#employee) do |f| %>
<% if #employee.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#employee.errors.count, "error") %> prohibited this employee from being saved:</h2>
<ul>
<% #employee.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :fonction %><br>
<%= f.select :fonction, Employee.fonction.map {|r| [r.humanize, r.camelcase]}, {}, disabled: #fonction != "Employee" %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And my employee controller
class EmployeesController < ApplicationController
before_action :set_employee, only: [:show, :edit, :update, :destroy]
before_action :set_fonction
def index
#employees = Employee.all
##employees = fonction_class.all
end
def show
end
def new
##employee = fonction_class.new
#employee = Employee.new
end
def edit
end
def create
#employee = Employee.new(employee_params)
if #employee.save
redirect_to #employee, notice: "#{fonction} was successfully created."
else
render action: 'new'
end
end
def update
end
def destroy
end
private
def fonction
params[:type] || "Employee"
end
def set_fonction
#fonction = fonction
end
# def fonction_class
# fonction.constantize
#end
def set_animal
#employee = fonction_class.find(params[:id])
end
def employee_params
params.require(fonction.downcase.to_sym).permit(:name, :fonction)
end
end
You need to define fonction in your model (app/models/employee.rb)
The way you're using it implies it's defined as both a class method, and an instance method. It also looks like it could be an array? Employee.fonction.map {|r| ... or an attribute (since you have a select to set it on an employee.)
However, you define fonction as a string...
def fonction
params[:type] || "Employee"
end
So I'm not really sure what you're trying to achieve here... All I know is Employee.fonction looks like a model class method...
def self.fonction
...
end
and f.select :fonction looks like an instance method or attribute?
EDIT I think I've got this... (Sorry, I missed fonction reference in your model definition)
Try adding this to your Employee model:
def self.fonction
["Manager", "Consultant", "Employee"]
end
EDIT #2
You can also define a constant in your model
FONCTIONS = ["Manager", "Consultant", "Employee"]
def fonction
FONCTIONS
end
Did you create fonction column?, create it by entering in your terminal, when in your app directory:
rails g migration add_fonction_to_employees fonction
rake db:migrate
Then check your DB has the column fonction in employees table.
I have two resources: Recommendations and Ratings.
Recommendations Model:
class Recommendation < ActiveRecord::Base
has_many :ratings
accepts_nested_attributes_for :ratings
end
Ratings Model:
class Rating < ActiveRecord::Base
belongs_to :recommendation
end
Recommendations Controller:
class RecommendationsController < ApplicationController
def index
#product = Product.find(params["product_id"])
#recommendations = Recommendation.find(:all, :joins => :products, :conditions => ["product_id = ?", (params["product_id"])])
#recommendation = Recommendation.new
#rating = Rating.new
end
def create
#need to find_or_create new rating based on recommendation_id
end
end
Recommendations Index:
<div id ="prods_container">
<%= form_for #recommendation do |f| %>
<%= f.fields_for #rating do |r| %>
<% #recommendations.each do |rec| %>
<%= rec.title %>
<div id="rec_note_text"><%= r.text_field :notes %></div>
<% end %>
<%= f.submit %>
<% end %>
<% end %>
</div>
I am trying to add a notes field for each of the "recommendation" objects which I need to update the ratings table in my create action/recommendations controller. How do I pass the correct ID's to my controller to achieve this?