Ruby on Rails - Pass ID from another controller - ruby-on-rails

I have two models. First is Taxirecord and second is Carpark. Each Taxirecord may have its own Carpark. I have a problem with passing taxirecord_id to Carpark record. I have route
car_new GET /taxidetail/:taxirecord_id/carpark/new(.:format) carparks#new
And i want to pass :taxirecord_id, which is id of taxirecord that im editing, to my create controller.
My carpark model:
class Carpark < ActiveRecord::Base
belongs_to :taxirecord
end
In controller im finding taxirecord_id by find function based on param :taxirecord_id, but id is nil when create is called. Can you please help me to find out what Im doing wrong and how Can I solve this problem? Thanks for any help!
My carpark controller
class CarparksController < ApplicationController
def new
#car = Carpark.new
end
def create
#car = Carpark.new(carpark_params, taxirecord_id: Taxirecord.find(params[:taxirecord_id]))
if #car.save
flash[:notice] = "Zaznam byl ulozen"
redirect_to root_path
else
flash[:notice] = "Zaznam nebyl ulozen"
render 'new'
end
end
private def carpark_params
params.require(:carpark).permit(:car_brand, :car_type, :driver_name, :driver_tel)
end
end

I finally get it work
Ive added <%=link_to 'New Carpark', {:controller => "carparks", :action => "new", :taxirecord_id => #taxi_record.id }%>
to my taxirecord form and to carpark form <%= hidden_field_tag :taxirecord_id, params[:taxirecord_id] %>
And to my carpark controller : #carpark.taxirecord_id = params[:taxirecord_id]
Thanks everyone for great support and help!

I'd lean towards using something like:
before_action :assign_taxirecord
...
private
def assign_taxirecord
#taxirecord = TaxiRecord.find(params[:taxirecord_id])
end
And then in the create action:
def create
#car = #taxirecord.build_carpark(carpark_params)
...
end
Obviously there's a little tailoring needed to your requirements (i.e. for what actions the before_action is called), but I hope that helps!

No need to send taxirecord id.
class Carpark < ApplicationRecord
belongs_to :taxirecord
end
class Taxirecord < ApplicationRecord
has_one :carpark
end
Rails.application.routes.draw do
resources :taxirecords do
resources :carparks
end
end
for new taxirecord
t = Taxirecord.new(:registration => "efgh", :description =>"test")
for new carpark
t.create_carpark(:description=>"abcd")
#=> #<Carpark id: 2, taxirecord_id: 2, description: "abcd", created_at: "2017-10-12 10:55:38", updated_at: "2017-10-12 10:55:38">

Related

Action Controller exception undefined method `merge' for xxx:String

I'm doing simple Reddit like site. I'm trying to add button to reporting posts. I create report model, using button_to i try to post data to report controller to create it but i received NoMethodError in ReportsController#create undefined method merge' for "post_id":String
model/report.rb
class Report < ApplicationRecord
belongs_to :reporting_user, class_name: 'Author'
has_one :post
end
report_controller.rb
class ReportsController < ApplicationController
def create
report = Report.new(report_params)
flash[:notice] = if report.save
'Raported'
else
report.errors.full_messages.join('. ')
end
end
def report_params
params.require(:post).merge(reporting_user: current_author.id)
end
end
and button in view
= button_to "Report", reports_path, method: :post, params: {post: post}
What cause that problem?
edit:
params
=> <ActionController::Parameters {"authenticity_token"=>"sX0DQfM0rp97q8i16LGZfXPoSJNx15Hk4mmP35uFVh52bzVa30ei/Bxk/Bm40gnFmd2NvFEqj+Wze8ted66kig==", "post"=>"1", "controller"=>"reports", "action"=>"create"} permitted: false>
To start with you want to use belongs_to and not has_one.
class Report < ApplicationRecord
belongs_to :reporting_user, class_name: 'Author'
belongs_to :post
end
This correctly places the post_id foreign key column on reports. Using has_one places the fk column on posts which won't work.
And a generally superior solution would be to make reports a nested resource:
# /config/routes.rb
resources :posts do
resources :reports, only: [:create]
end
# app/controller/reports_controller.rb
class ReportsController
before_action :set_post
# POST /posts/:post_id/reports
def create
#report = #post.reports.new(reporting_user: current_author)
if #report.save
flash[:notice] = 'Reported'
else
flash[:notice] = report.errors.full_messages.join('. ')
end
redirect_to #post
end
private
def set_post
#post = Post.find(params[:post_id])
end
end
This lets you simplify the button to just:
= button_to "Report", post_reports_path(post), method: :post
Since the post_id is part of the path we don't need to send any additional params.
If you do want to let the user pass additional info through a form in the future a better way to create/update resources with params and session data is by passing a block:
#report = #post.reports.new(report_params) do |r|
r.reporting_user = current_user
end
ActionController::Parameters#require returns the value of the required key in the params. Usually this would be an object passed back from a form. In this example require would return {name: "Francesco", age: 22, role: "admin"} and merge would work.
Your view is sending back parameters that Rails is formatting into {post: 'string'}. We would need to see your view code to determine what exactly needs to change.
Update: From the new code posted we can see that the parameter sent back is "post"=>"1". Normally we would be expecting post: {id: 1, ...}.
Update: The button in the view would need the params key updated to something ala params: {post: {id: post.id}} EDIT: I agree that params: {report: { post_id: post}} is a better format.
The problem seems to be in report_params. When you call params.require(:post), it fetches :post from params -> the result is string. And you are calling merge on this string.
I'd recommend change in view:
= button_to "Report", reports_path, method: :post, params: { report: { post_id: post} }
then in controller:
def report_params
params.require(:report).permit(:post_id).merge(reporting_user_id: current_author.id)
end
Note, that I changed also the naming according to conventions: model_id for id of the model, model or model itself.

I keep getting an undefined method for a class

I've been searching and searching but I cannot find anything to help me with this. I am building an app that allows you to schedule a meeting in a room. The error I'm receiving is
undefined method 'room_id' for #<Room:0x007fa25cc51128>
Here is where the error is occuring in my application.html.erb:
<li><%= link_to "Schedule a Meeting", new_room_meeting_path(#user, #meeting, #room.room_id)%></li>
Here is my meetings controller:
class MeetingsController < ApplicationController
before_action :authenticate_user!
def new
#meeting = Meeting.new
#rooms = Room.all
#room = Room.find(params[:room_id])
end
def index
#meetings = Meeting.all
end
def show
#meeting = Meeting.find(params[:id])
#comments = #meeting.comments
#room = Room.find(params[:id])
end
def create
#user = User.find(params[:user_id])
#meeting = #user.meetings.create(meeting_params)
NotificationMailer.meeting_scheduled(#meeting).deliver_now
if #meeting.save
redirect_to root_path, flash: { notice: "Congratulations!!! Your meeting has been scheduled successfully!!!"}
else
render :new
end
end
private
def meeting_params
params.require(:meeting).permit(:name, :start_time, :end_time, :user_id, :room_id)
end
end
Here is my Meeting model:
require 'twilio-ruby'
class Meeting < ActiveRecord::Base
belongs_to :user
belongs_to :room
has_many :comments
validates_presence_of :user_id, :room_id, :name
def meeting_author_email
user.try(:email)
end
def self.send_reminder_text_message(body, phone)
#account_sid = ENV['twilio_account_sid']
#auth_token = ENV['twilio_auth_token']
#from_phone_number = ENV['twilio_phone_number']
#twilio_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#twilio_client.account.messages.create( to: phone,
from: #from_phone_number,
body: body
)
end
def start_timestamp
(start_time - 6.hours).strftime('%b %e, %l:%M %p')
end
def end_timestamp
(end_time - 6.hours).strftime('%b %e, %l:%M %p')
end
end
The correct URI is: /rooms/:room_id/meetings/new(.:format)
I don't know what the problem is and it is really frustrating me. Any help would be greatly appreciated. I've searched over and over and have been unable to resolve this.
Thanks.
Your Room model doesn't have a column called room_id, but it does have a column called id. Every object in your application has an automatically generated id column as part of the "magic" of Rails. The room_id column that you seem to want belongs to the meetings table, but you indicated that it should come from your room object.
Replace the line:
Schedule a Meeting", new_room_meeting_path(#user, #meeting, #room.room_id)%></li>
with:
Schedule a Meeting", new_room_meeting_path(#user, #meeting, #meeting.room_id)%></li>
Since you stated the URI is "/rooms/:room_id/meetings/new(.:format)", the first part of the fix is to use the :id attribute instead of the: room_id attribute on your #room object, and second to remove the unnecessary objects from your route. You only need the id attribute for a valid URI:
<li><%= "Schedule a Meeting", new_room_meeting_path(#room.id)%></li>
Turns out I was calling the wrong URI.. The correct one was:
<li><%= link_to "Schedule a Meeting", new_user_meeting_path(current_user) %></li>
Is what did the trick. I also made the mistake of not dealing with seed data properly which really threw me for a loop. So once again, THANKS again to all who helped me out. I was working on an old project so I had a lot to go over.

Can't test a controller when passing a hidden field

I have two objects, Course and TeacherRight. I create TeacherRight with a from placed on the Course 'show' view. I pass course_id to the TeacherRight controller as a hidden field:
=form_for(#right) do |f|
=hidden_field_tag :course_id, #course.id
%ul
%li=f.collection_select :user_id, User.order(:name)-#course.teachers, :id, :name, include_blank: false
%li=f.submit
The controller:
class TeacherRightsController < ApplicationController
def create
course = Course.find(params[:course_id])
#teacher_right = course.teacher_rights.build(teacher_right_params)
#teacher_right.save
redirect_to course
end
private
def teacher_right_params
params.require(:teacher_right).permit(:user_id)
end
#only owner can add teachers to course
def can_edit(course)
redirect_to root_url unless current_user == course.owner
end
It works fine, but I can't write a test for it! I wrote
class TeacherRightsControllerTest < ActionController::TestCase
def setup
#owner_1 = users(:owner_1)
#course = courses(:course)
#teacher_1 = users(:teacher_1)
end
test "teacher can't add teachers" do
log_in_as(#teacher_1)
assert_no_difference('TeacherRight.count') do
post :create, {teacher_right: {course_id:#course.id, user_id: #teacher_1.id }}
end
end
But it gives an error:
ActiveRecord::RecordNotFound: Couldn't find Course with 'id'=
app/controllers/teacher_rights_controller.rb:4:in `create'
As I can see,
post :create, {teacher_right: {course_id:#course.id, user_id: #teacher_2.id, }}
doesn't pass course_id in a way the controller can consume. How can I correct it?
You accidentally are posting the :course_id inside the :teacher_right hash, so it will show up as params[:teacher_right][:course_id] instead of the desired params[:course_id].
Your POST request should look like this:
post :create, {
course_id: #course.id,
teacher_right: { user_id: #teacher_1.id }
}

Rails 4.0.2 ActionController::ParameterMissing in AuctionsController#create param not found:

I am creating an auction website and I get an error when I run a command to create a new auction.
The model is simple:
class Auction < ActiveRecord::Base
has_many :bets
has_many :profiles, :through => :bets
and etc.
The controller: `
class AuctionsController < ApplicationController
def new
#auction = Auction.new
end
def create
#auction = Auction.new(auction_params)
if #auction.save
redirect_to(:action => 'index')
else
render('new')
end
end
private
def auction_params
params.require(:auction_email).permit(:auction_description, :auction_location, :auction_deadline, :auction_title, bets_attributes: [ :bet_size], )
end
end
The new.html.erb has form in this way:
<%= form_for(:auction, :url => {:action => 'create'}) do |f| %>
<%= f.text_field(:auction_title) %>
and so on for every entry.
The error message is:
ActionController::ParameterMissing in AuctionsController#create param not found: auction_email
I have been trying to solve it with "if params[:status]", but it returns an empty form and database remains empty.
Rails version 4.0.2
Use this
def auction_params
params.require(:auction).permit(:auction_email,:auction_description, :auction_location, :auction_deadline, :auction_title, bets_attributes: [ :bet_size], )
end
Assuming that Auction is your model.
params.require argument should be :auction(:modelname) and in permit method you pass the atrributes like :auction_email(:attributename) that you would like to insert/update in database.

The action 'create' could not be found for WatchedWatchersController

I've searched high and low for this and the other solutions don't seem to help.
The error:
The action 'create' could not be found for WatchedWatchersController
I get this after clicking a link made with this code in a view:
<%= link_to 'Watchlist', { :controller => "watched_watchers",
:action => "create",
:watcher_id => current_user.id,
:watched_id => user.id},
:method => "post" %>
My model for this class is:
class Watched_Watcher < ActiveRecord::Base
attr_accessible :watched_id, :watcher_id
validates :watched_id, :watcher_id, presence: true
end
And my controller is:
class WatchedWatchersController < ApplicationController
def new
end
def create
#ww = Watched_Watcher.new
#ww.watcher_id = params[:watcher_id]
#ww.watched_id = params[:watched_id]
#ww.save
end
def update
end
def edit
end
def destroy
end
def index
end
def show
end
end
I've set up my routes as a RESTful resource:
resources :watched_watchers
And rake routes reveals:
POST /watched_watchers(.:format) watched_watchers#create
So I'm stumped and any help is appreciated. Thanks in advance.
Vimsha's comment solved it
"Rename your model to WatchedWatcher(no underscore)". And then once I fixed the model name I just needed to have a redirect back to the same page.

Resources