Ruby Project Help. Can't Get Saved Instances from Array

Can't get my strong parameters nested correct in Ruby on Rails

As per rails documentation Nested attributes allow you to save attributes on associated records through the parent. So in your strong params you need to pass attributes like this.

params.permit(:name, :description, task_attributes: [:name, :start, :end])

I suggest you to bind all params under one attribute like this

params.require(:project).permit(:name, :description, task_attributes: [:name, :start, :end])

so you must send params from frontend like

{"project": {"name"=>"asdf", "description"=>"zxvccxvzzxcvxcvcxvzxcvz", "task_attributes"=>[{"start"=>"2019-12-05T03:38:48.555Z", "end"=>"2019-12-14T03:38:48.555Z", "name"=>"Some task"}]}}

You can read the documentation from https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

How to pass an array between Ruby files

You can't pass an array from a ruby file to another one., you only can pass data between classes and objects.

Other possibilities which may help:

  • constants (Defined with starting capital letter)
  • global variables (starting with $)
  • Singletons

To keep data inside the class instances (objects) you need attributes (variables starting with @).

You can find this concepts in every beginner manual of ruby (and if not, then the manual is not worth to be used)


You made another common error.

Let's check it with a small example:

class Company
attr_accessor :jobs
def initialize()
jobs='This should be assigned to my accessor jobs'
end
end

puts Company.new.jobs

The result is an empty line.

What happend? In the initialize-method you define a local variable jobs. Local means, it is only available in the method ans is lost when the method leaves.

Correct would be 1) using the instance variable:

class Company
attr_accessor :jobs
def initialize()
@jobs='This should be assigned to my accessor jobs'
end
end

or 2) using the accessor method:

class Company
attr_accessor :jobs
def initialize()
self.jobs='This should be assigned to my accessor jobs'
end
end

In both cases the puts Company.new.jobs returns the text you defined.

See also Ruby instance variable access

Ruby on Rails: finding a model instance from a different controller

Simplest way is add the id as a hidden field. Your strong params should take care of project_id it looks like:

<%= form_for @invitation do |f| %>
<%= f.hidden_field :project_id, @project.id %>
<%= f.collection_select :user_id, User.all, :id, :first_name %><br>
<%= f.submit "Send Invitation", class: "btn btn-primary" %>
<% end %>

Then in your controller, just use the params to make a new one. Passing the id through the new method will associate the record for you.

def create
@invitation = Invitation.new invitation_params
if @invitation.save
flash[:success] = "Invitation sent!"
redirect_to @invitation
else
render 'new'
end
end

Also note, when you call create_invitation that actually calls the create method right there. So it's already saved. The corresponding to new where it's just built in memory is build_invitation(invitation_params)

Passing in an array into form_for() and link_to()

Nesting resources route from an URL that contains the ID of both resources, in this case something like: /projects/1/tickets/10. To generate this URL, we need to know the id of both the project and the ticket, so both of these objects need to be passed in.

An edit URL goes further, and adds an action keyword - /projects/1/tickets/10/edit, so again we need to pass in this action.

A RESTful destroy route in Rails, however, uses the HTTP method DELETE instead of an action keyword, so the URL to destroy your ticket really is /projects/1/tickets/10; just with a DELETE request instead of GET.

For more information, I'd recommend reading through Rails Routing from the Outside In

Rails 4: How to use includes() with where() to retrieve associated objects

The user object is not part of the project object, so you won't be able to view it on the project: rather, by saying Project.includes(:user), you're telling Rails to eager-load the referenced association when it finds the project. This saves you a database call down the road. For example, non-eagerly:

@project = Project.where(id: params[:id]).first # one database call, fetching the project
@project.user # another database call, fetching the user

And eagerly:

@project = Project.includes(:user).where(id: params[:id]).first # one database call, fetching both project and user
@project.user # no database interaction

This matters more with has_many queries where eager-loading associations can save N+1 database queries.

You can verify this is working appropriately by calling @project.user at some point after the eager load and checking your logs: you should see that there was no database call at that point.



Related Topics



Leave a reply



Submit