Rails Displaying a category name from a belongs_to - ruby-on-rails

I would like to display a category name instead of a number (cat_id) from a belongs to relationship, I have cars and makes, basically here's the code -
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Make:</b>
<%= #car.make_id %>
</p>
<h2>
<em><%= #car.model %> <%= #car.body_typw %> <%= #car.engine_size %> <%= #car.trim %></em>
</h2>
<p>
<%= image_tag #car.image(:large) %>
</p>
<% #carimages.each do |carimage| %>
<%= image_tag carimage.image(:thumb), :class => "imgsmall" %>
<% end %>
<p>
<b>Transmission:</b>
<%= #car.transmission %>
</p>
<p>
<b>Fuel type:</b>
<%= #car.fuel_type %>
</p>
<p>
<b>Millage:</b>
<%= #car.millage %>
</p>
<p>
<b>Price:</b>
<%= number_to_currency(#car.price) %>
</p>
<p>
<%= raw #car.content %>
</p>
So basically i want the Make name here:-
<p>
<b>Make:</b>
<%= #car.make_id %>
</p>
cars_controller.rb
class CarsController < ApplicationController
# GET /cars
# GET /cars.json
def index
#cars = Car.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #cars }
end
end
# GET /cars/1
# GET /cars/1.json
def show
#car = Car.find(params[:id])
#pages = Page.all
#carimages = Carimage.all
#carimages = Carimage.find(:all, :limit => 10, :order => "id DESC")
respond_to do |format|
format.html # show.html.erb
format.json { render json: #car }
end
end
# GET /cars/new
# GET /cars/new.json
def new
#car = Car.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #car }
end
end
# GET /cars/1/edit
def edit
#car = Car.find(params[:id])
end
# POST /cars
# POST /cars.json
def create
#car = Car.new(params[:car])
respond_to do |format|
if #car.save
format.html { redirect_to #car, notice: 'Car was successfully created.' }
format.json { render json: #car, status: :created, location: #car }
else
format.html { render action: "new" }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
end
end
# PUT /cars/1
# PUT /cars/1.json
def update
#car = Car.find(params[:id])
respond_to do |format|
if #car.update_attributes(params[:car])
format.html { redirect_to #car, notice: 'Car was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
end
end
# DELETE /cars/1
# DELETE /cars/1.json
def destroy
#car = Car.find(params[:id])
#car.destroy
respond_to do |format|
format.html { redirect_to cars_url }
format.json { head :ok }
end
end
end
it is related through make table - id and car table - make_id
Thanks
Robbie

Sure - the belongs to relationship gives you an object (a Make in your case), which you can call methods on - including getting field names!
So, If you set up your models like so:
class Car < ActiveRecord::Base
belongs_to :make
end
class Make < ActiveRecord::Base
end
And Make has a field named name, you could in your view:
<p>
<b>Make:</b>
<%= #car.make.name %>
</p>

Related

When a Post comment is made, no more can be created, only shown

I am trying to get a post and comment system working, for this however i want only one comment to be made per post. Only as i am trying to create a system as where content will be displayed followed by a comment 7 times in one post... Example...
program model 1 body content 1
Commentmodel1
program model 1 body content 2
Commentmodel2
program model 1 body content 3
Commentmodel3
.etc.etc.
For Me this is the simplest way of being able todo this by creating 7 different comment models, i know there is probably an easier way but as im new this seems the simplest. However i am struggling getting the one comment model to only allow just one comment to be made.
In this application coach is the user.
Here are the files involved, For the Models, program is the basic Post model, and comments is comments.
programs/Show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Title:</b><br />
<%= #program.title %>
</p>
<p>
<b>Body:</b><br />
<%= #program.cweekcomments %>
</p>
<%= link_to 'Edit', edit_program_path(#program) %> |
<%= link_to 'Back', programs_path %>
<br /><br /><br />
<i>Comments</i>
<% #program.comments.each do |comment| %>
<p>
<b>Comment:</b>
<% if comment %>
<%= comment.body %>
<br />
<%= link_to 'Edit', edit_program_comment_path(#program, comment) %> | <%= link_to 'Destroy', [#program, comment] , method: :delete, data: { confirm: 'Are you sure?' } %>
<% else %>
<%= form_for([#program, #program.comments.build]) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<% end %>
</p>
<% end %>
Programs_controller.rb
class ProgramsController < ApplicationController
before_filter :authenticate_coach!, :except => [:show]
# GET /programs
# GET /programs.json
def index
#programs = Program.find_all_by_coach_id(current_coach[:id])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #programs }
end
end
# GET /programs/1
# GET /programs/1.json
def show
#program = Program.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #program }
end
end
# GET /programs/new
# GET /programs/new.json
def new
#program = Program.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #program }
end
end
# GET /programs/1/edit
def edit
#program = Program.find(params[:id])
end
# POST /programs
# POST /programs.json
def create
#program = Program.new(params[:program])
respond_to do |format|
if #program.save
format.html { redirect_to #program, notice: 'Program was successfully created.' }
format.json { render json: #program, status: :created, location: #program }
else
format.html { render action: "new" }
format.json { render json: #program.errors, status: :unprocessable_entity }
end
end
end
# PUT /programs/1
# PUT /programs/1.json
def update
#program = Program.find(params[:id])
respond_to do |format|
if #program.update_attributes(params[:program])
format.html { redirect_to #program, notice: 'Program was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #program.errors, status: :unprocessable_entity }
end
end
end
# DELETE /programs/1
# DELETE /programs/1.json
def destroy
#program = Program.find(params[:id])
#program.destroy
respond_to do |format|
format.html { redirect_to programs_url }
format.json { head :no_content }
end
end
end
Comments_controller.rb
class CommentsController < ApplicationController
def new
#comment = #program.comments.build
end
def create
#program = Program.find(params[:program_id])
#comment = #program.comments.create(params[:comment])
redirect_to program_path(#program)
end
def destroy
#program = Program.find(params[:program_id])
#comment = #program.comments.find(params[:id])
#comment.destroy
redirect_to program_path(#program)
end
def edit
#program = Program.find(params[:program_id])
#comment = #program.comments.find(params[:id])
end
def update
#program = Program.find(params[:program_id])
#comment = #program.comments.find(params[:id])
respond_to do |format|
#if #program.comments.update_attributes(params[:comment])
if #comment.update_attributes(params[:comment])
format.html { redirect_to program_path(#program), notice: 'Comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
end
In advance, thanks for your help, much appreciated!
Change your program comment relation to has_one.(has_one :comment in your program.rb)
def create
#program = Program.find(params[:program_id])
if #program.comment
flash[:error] = "Cannot comment more than once"
else
#comment = #program.comments.create(params[:comment])
flash[:notice] = "Comment created"
end
redirect_to program_path(#program)
end

Getting a "NoMethodError in Boards#show" error when going to #new action (not trying to access a method, and the variable exists)

I'm very new to Ruby on Rails, so forgive if this is a stupid mistake.
I used a rails generate scaffold command to generate a "board" scaffold with a title:string and message:text. Now, I'm trying to go to localhost:3000/boards/new and I'm getting a "NoMethodError in Boards#show" error when I try to access board.message. I don't get any error when I try to access board.title.
Code:
form.html.erb
<%= form_for(#board) do |f| %>
<% if #board.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#board.errors.count, "error") %> prohibited this board from being saved:</h2>
<ul>
<% #board.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :message %><br />
<%= f.text_area :message %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I'm specifically getting the error on line 20 (<%= f.text_area :message %>)
board.rb
class Board < ActiveRecord::Base
attr_accessible :message, :title
has_many :posts
end
*boards_controller.rb*
class BoardsController < ApplicationController
# GET /boards
# GET /boards.json
def index
#boards = Board.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #boards }
end
end
# GET /boards/1
# GET /boards/1.json
def show
#board = Board.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #board }
end
end
# GET /boards/new
# GET /boards/new.json
def new
#board = Board.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #board }
end
end
# GET /boards/1/edit
def edit
#board = Board.find(params[:id])
end
# POST /boards
# POST /boards.json
def create
#board = Board.new(params[:board])
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
# PUT /boards/1
# PUT /boards/1.json
def update
#board = Board.find(params[:id])
respond_to do |format|
if #board.update_attributes(params[:board])
format.html { redirect_to #board, notice: 'Board was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
# DELETE /boards/1
# DELETE /boards/1.json
def destroy
#board = Board.find(params[:id])
#board.destroy
respond_to do |format|
format.html { redirect_to boards_url }
format.json { head :no_content }
end
end
end
routes.rb
Anonymous::Application.routes.draw do
resources :boards
resources :posts
root :to => "boards#index"
end
Can anyone please explain this to me?

redirect using a form

this form (views/workers/_form.html.erb) redirects me to the index of tasksadmins, after I push the 'create tasksadmin' button.
I want it to redirect me to "workers/index" and change the button to 'update the task'.
how can I do that please?
<%= form_for(#tasksadmin) do |f| %>
<% if #tasksadmin.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#tasksadmin.errors.count, "error") %> prohibited this tasksadmin from being saved:</h2>
<ul>
<% #tasksadmin.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :admin_mail, :value => #tasksadmin.admin_mail %>
<%= f.hidden_field :worker_mail, :value => #worker_mail %>
<%= f.hidden_field :task, :value => #tasksadmin.task %>
<div class="field">
<%= f.label :done %><br />
<%= f.check_box :done %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
and this is my workers_controller:
class WorkersController < ApplicationController
# GET /workers
# GET /workers.json
def index
#tasks_worker = Tasksadmin.where(:worker_mail => "alon.shmiel#gmail.com")
respond_to do |format|
format.html # index.html.erb
format.json { render json: #workers }
end
end
# GET /workers/1
# GET /workers/1.json
def show
#task_worker = Tasksadmin.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #worker }
end
end
# GET /workers/new
# GET /workers/new.json
def new
#worker = Worker.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #worker }
end
end
# GET /workers/1/edit
def edit
#tasksadmin = Tasksadmin.find(params[:id])
#worker_mail = "alon.shmiel#gmail.com"
end
# POST /workers
# POST /workers.json
def create
#worker = Worker.new(params[:worker])
respond_to do |format|
if #worker.save
format.html { redirect_to "#worker", notice: 'Worker was successfully created.' }
format.json { render json: #worker, status: :created, location: #worker }
else
format.html { render action: "new" }
format.json { render json: #worker.errors, status: :unprocessable_entity }
end
end
end
# PUT /workers/1
# PUT /workers/1.json
def update
#worker = Tasksadmin.find(params[:id])
respond_to do |format|
if #worker.update_attributes(params[:worker])
format.html { render action: "index", notice: 'Worker was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #worker.errors, status: :unprocessable_entity }
end
end
end
# DELETE /workers/1
# DELETE /workers/1.json
def destroy
#worker = Tasksadmin.find(params[:id])
#worker.destroy
respond_to do |format|
format.html { render action: "index" }
format.json { render json: #worker }
end
end
end
In your controller, you have to redirect to the appropriate path like so:
def update
redirect_to "workers/index"
end
I would suggest using path helpers so if you have your routes set up as resources, you can do this:
redirect_to workers_path
As for changing the the button text, just change it to:
f.submit("update the task")
You create a form for an object #tasksadmin, which in your WorkersController#edit is set as follows:
#tasksadmin = Tasksadmin.find(params[:id]
This means that that parameter contains an object of class Tasksadmin, if you let rails build the path for the a Tasksadmin, it will send you to the TasksadminsController#update, and that is why your code does not work. You never get to the WorkersController#update. Check your logs to verify that.
Let me be very clear about this: you should not edit Tasksadmin objects in the WorkersController.
I do not understand why you would do that.

find_or_create_by_name not working when trying to associate tasks with lists on todolist app

Rails newbie working on associating tasks with lists and running into trouble when I try and interact with forms after I start the rails server.
Here's the error I'm getting. Any ideas?
Thanks!
NoMethodError in TasksController#create
undefined method `find_or_create_by_name' for #<Class:0x00000102a8bad0>
Rails.root: /Users/user/rails_projects/todolist
Application Trace | Framework Trace | Full Trace
app/models/task.rb:15:in `list_name='
app/controllers/tasks_controller.rb:43:in `new'
app/controllers/tasks_controller.rb:43:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"B7g7u+v5USPRhefdFPt84xGkKjB1nVwy62IJj6SHJpc=",
"task"=>{"description"=>"Milk",
"list_name"=>"Shopping"},
"commit"=>"Create Task"}
ListsController:
class ListsController < ApplicationController
# GET /lists
# GET /lists.json
def index
#lists = List.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #lists }
end
end
# GET /lists/1
# GET /lists/1.json
def show
#list = List.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #list }
end
end
# GET /lists/new
# GET /lists/new.json
def new
#list = List.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #list }
end
end
# GET /lists/1/edit
def edit
#list = List.find(params[:id])
end
# POST /lists
# POST /lists.json
def create
#list = List.new(params[:list])
respond_to do |format|
if #list.save
format.html { redirect_to #list, notice: 'List was successfully created.' }
format.json { render json: #list, status: :created, location: #list }
else
format.html { render action: "new" }
format.json { render json: #list.errors, status: :unprocessable_entity }
end
end
end
# PUT /lists/1
# PUT /lists/1.json
def update
#list = List.find(params[:id])
respond_to do |format|
if #list.update_attributes(params[:list])
format.html { redirect_to #list, notice: 'List was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /lists/1
# DELETE /lists/1.json
def destroy
#list = List.find(params[:id])
#list.destroy
respond_to do |format|
format.html { redirect_to lists_url }
format.json { head :no_content }
end
end
end
TasksController:
class TasksController < ApplicationController
# GET /tasks
# GET /tasks.json
def index
#tasks = Task.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #tasks }
end
end
# GET /tasks/1
# GET /tasks/1.json
def show
#task = Task.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #task }
end
end
# GET /tasks/new
# GET /tasks/new.json
def new
#task = Task.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #task }
end
end
# GET /tasks/1/edit
def edit
#task = Task.find(params[:id])
end
# POST /tasks
# POST /tasks.json
def create
#task = Task.new(params[:task])
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render json: #task, status: :created, location: #task }
else
format.html { render action: "new" }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# PUT /tasks/1
# PUT /tasks/1.json
def update
#task = Task.find(params[:id])
respond_to do |format|
if #task.update_attributes(params[:task])
format.html { redirect_to #task, notice: 'Task was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tasks/1
# DELETE /tasks/1.json
def destroy
#task = Task.find(params[:id])
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url }
format.json { head :no_content }
end
end
end
Task model:
class Task < ActiveRecord::Base
attr_accessible :description, :list_name
belongs_to :list, :foreign_key => "list_id"
def name
#list = List.find(params[:id])
end
def list_name
list.name if self.list
end
def list_name=(str)
self.list = List.find_or_create_by_name(str)
end
end
List model:
class List < ActiveRecord::Base
attr_accessible :title
has_many :tasks
def name
#list = List.find(params[:id])
end
end
Partial for Tasks:
<%= form_for(#task) do |f| %>
<% if #task.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#task.errors.count, "error") %> prohibited this task from being saved:</h2>
<ul>
<% #task.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :list_name %><br />
<%= f.text_field :list_name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Partial for Lists:
<%= form_for(#list) do |f| %>
<% if #list.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#list.errors.count, "error") %> prohibited this list from being saved:</h2>
<ul>
<% #list.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The dynamic finders find_or_create_by_*... have been deprecated in Rails 4, as can be read about here.
However find_or_create_by is still supported.
In other words, instead of
find_or_create_by_name( 'Alice' ) # DEPRECATED
do
find_or_create_by( name: 'Alice' ) # OK
Rails' dynamic finders (find_by_... and find_or_create_by_...) are generated using the attributes of a model. You were using find_or_create_by_name when name wasn't an attribute on the List model.
Changing that to find_or_create_by_title(...) fixes the problem.

Ruby on Rails modify references

So my initial question was Association Ruby on Rails. However when referring to a post the issue that i am having is that its blank. Don't see anything. After researching I believe is because when i created my test post I didn't define a customer related to it.
class CustomersController < ApplicationController
before_filter :signed_in_customer, only: [:edit, :update]
before_filter :correct_customer, only: [:edit, :update]
def index
#customers = Customer.all
end
def show
#customer = Customer.find(params[:id])
**#posts = #customer.posts**
end
Here the form that allow me to create a post for the moment.
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label :frienship_group_id %><br />
<%= f.text_field :frienship_group_id %>
</div>
<div class="field">
<%= f.label :post_size_id %><br />
<%= f.text_field :post_size_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Which is what i am using when creating a new form. How i am suppose to allow customization to update the field that this is related to the current user in the customer_id field?
Here the model
class Post < ActiveRecord::Base
belongs_to :customer
validates :title, presence: true
validates :description, presence: true
validates :customer_id, presence: true
validates :frienship_group_id, presence: true
validates :Post_size_id, presence: true
Update:
Here my new.html.erb for post
<h1>New post</h1>
<%= render 'form' %>
<%= link_to 'Back', posts_path %>
Here the controller
class PostsController < ApplicationController
# GET /posts
# GET /posts.json
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #post }
end
end
# GET /posts/new
# GET /posts/new.json
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.json
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
end
I'm fairly new to Rails, but I think this is how you do it. I'm assuming that your currently logged in user is current_user.
def create
#post = current_user.posts.build(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end

Resources