I have a scenario which needs a very complex form, and i need help in it.
I have three tables
create_table "permissions", :force => true do |t|
t.boolean "can_read"
t.boolean "can_create"
t.boolean "can_edit"
t.boolean "can_delete"
t.integer "role_id"
t.integer "resource_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "resources", :force => true do |t|
t.string "class_name"
t.string "class_action"
t.text "description"
t.integer "parent_resource"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "roles", :force => true do |t|
t.string "name"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
end
with the models and associations
class Role < ActiveRecord::Base
has_many :user_roles
has_many :users, :through => :user_roles
has_many :permissions
def to_s
self.name
end
end
class Resource < ActiveRecord::Base
has_many :permissions
has_many :children, :class_name => "Resource", :foreign_key => "parent_resource"
scope :root, lambda {
{
:conditions => "parent_resource IS NULL"
}
}
end
class Permission < ActiveRecord::Base
belongs_to :role
belongs_to :resource
end
Suppose we have 2 roles, admin, user, this time, i need a form structure like the image in the this link
How can i make this form? Thanks in advance.
I created a gem that makes it easier to handle nested forms inside formtastic: formtastic_cocoon.
That should get you started.
Related
I'm building three models in my rails application. One model references the same model twice as shown in my DB Schema. The only problem is that when I make a POST Request to create a new record in my shipment table. I get this error:
#<ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: users.sender_id: SELECT \"users\".* FROM \"users\" WHERE \"users\".\"sender_id\" = ? LIMIT ?>
I don't think that I need to add a sender_id & receiver_id column in my users table because the sender_id & receiver_id are basically the User_ID in the users column. Any help would be much appreciated it!
This is my user.rb file:
class User < ApplicationRecord
has_many :shipments
end
This is my shipment.rb
class Shipment < ApplicationRecord
belongs_to :sender, class_name: "User", primary_key: "sender_id"
belongs_to :receiver, class_name: "User", primary_key: "receiver_id"
validates_uniqueness_of :tntcode
end
This is my shipments_controller:
class ShipmentsController < ApplicationController
def index
shipments = Shipment.all
end
def show
shipment = Shipment.find(params[:id])
end
def create
shipment = Shipment.new(shipment_params)
if shipment.save
render json: {status: 'Shipment created successfully'}, status: :created
else
render json: { errors: shipment.errors.full_messages }, status: :bad_request
end
end
def shipment_params
params.require(:shipment).permit(:tntcode, :status, :shipment_type, :weight, :content, :price, :sender_id, :receiver_id)
end
end
And my schema.rb:
ActiveRecord::Schema.define(version: 20180826123320) do
create_table "shipments", force: :cascade do |t|
t.integer "tntcode"
t.string "status"
t.string "shipment_type"
t.integer "weight"
t.string "content"
t.integer "price"
t.integer "sender_id"
t.integer "receiver_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["receiver_id"], name: "index_shipments_on_receiver_id"
t.index ["sender_id"], name: "index_shipments_on_sender_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email", null: false
t.string "role"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "photourl"
t.string "userid"
end
end
You don't want to change the primary_key on your belongs_to associations: that's the other table's ID column (id).
You instead want:
belongs_to :sender, class_name: "User", foreign_key: "sender_id"
belongs_to :receiver, class_name: "User", foreign_key: "receiver_id"
... which is the default, so this should work too:
belongs_to :sender, class_name: "User"
belongs_to :receiver, class_name: "User"
I have a has_many :through association.
#app/user.rb
class User < ApplicationRecord
has_many :members
has_many :projects, :through => :members
end
#app/project.rb
class Project < ApplicationRecord
has_many :members
has_many :users, :through => :members
end
#app/member.rb
class Member < ApplicationRecord
belongs_to :user
belongs_to :project
end
I have the database schema as follows:
create_table "members", force: :cascade do |t|
t.integer "user_id"
t.integer "project_id"
t.integer "is_owner"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["project_id"], name: "index_members_on_project_id"
t.index ["user_id"], name: "index_members_on_user_id"
end
create_table "projects", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
I can get Member ID, User_ID, Project_ID, and is_owner when I use the command #project.members
I can get user_id, first_name, last_name, email, and password when I use the command #project.users
What command should I use to get member_id, first_name, last_name?
I can get what I want using the SQL query SELECT * FROM members INNER JOIN users ON users.id = members.user_id but I don't want to use raw SQL.
Can someone tell me how to convert that query into a Ruby on rails command?
You can get your desired result using following code
Member.joins(:user)
It will generate the same query what you are specifying in your question i.e.
SELECT * FROM members INNER JOIN users ON users.id = members.user_id
I just want to make a little join table, eventually storing extra info on that join (which is why I'm not using HABTM). From the rails documentation of associations I've created the following models:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, :through => :appointments
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physicians
belongs_to :patients
end
my schema looks like this:
ActiveRecord::Schema.define(:version => 20130115211859) do
create_table "appointments", :force => true do |t|
t.datetime "date"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "patient_id"
t.integer "physician_id"
end
create_table "patients", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "physicians", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
When I'm in the console and I create a physician and patient instance:
#patient = Patient.create!
#physician = Physician.create!
And try to associate one to the other
#physician.patients << #patient
I get
NameError: uninitialized constant Physician::Patients
Questions about this example have been asked before but none have address my scenario. Any ideas?
Thanks,
Neil, rails newbie.
The belongs_to calls in your Appointment model should take a singular form, not a plural form:
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
I have a model Country (which is the same as 'Team') and a model Match and I am trying to build a scenario where I have a Match record with both home & away teams.
The models
class Country < ActiveRecord::Base
has_many :home_matches, :foreign_key => 'home', :class_name => "Match"
has_many :away_matches, :foreign_key => 'away', :class_name => "Match"
end
class Match < ActiveRecord::Base
belongs_to :home, :class_name => "Country", :foreign_key => "home"
belongs_to :away, :class_name => "Country", :foreign_key => "away"
end
The schemas
create_table "countries", :force => true do |t|
t.string "name"
t.text "bio"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "matches", :force => true do |t|
t.datetime "matchdate"
t.integer "home"
t.integer "away"
t.datetime "created_at"
t.datetime "updated_at"
end
Problem
This works well if I just want:
> canada.away_matches
> japan.home_matches
But how do I get all matches that a country is playing?
Update:
I found the answer in another reply.
ActiveRecord has two association
I have updated my Country model with the following code:
def matches
Match.where("home = ? OR away = ?", self, self)
end
Now I can query:
> canada.home_matches
> canada.away_matches
> canada.matches
And get the desired result.
You are setting up the associations in a wrong way.
Go through this
Single_Table_Inheritance wiki, and
single-table-inheritance-and-where-to-use-it-in-rails
I am struggling with a polymorphic many-to-many association in rails 3.
My Article model looks like this:
class Article < ActiveRecord::Base
has_many :article_tags
has_many :people, :through => :article_tags, :source => :taggable, :source_type => :person
end
My ArticleTag model looks like this:
class ArticleTag < ActiveRecord::Base
belongs_to :article
belongs_to :taggable, :polymorphic => true
end
My Person model looks like this:
class Person < ActiveRecord::Base
has_many :article_tags, :as => :taggable
end
Finally, my Organization model looks like this:
class Organization < ActiveRecord::Base
has_many :article_tags, :as => :taggable
end
I have a schema which looks like this:
ActiveRecord::Schema.define(:version => 20110322234836) do
create_table "article_tags", :force => true do |t|
t.integer "taggable_id"
t.string "taggable_type"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "articles", :force => true do |t|
t.string "title"
t.text "content"
t.date "published_on"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "people", :force => true do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "organizations", :force => true do |t|
t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
end
end
I was hoping that this would allow me to create people and organizations relationships from my articles like this:
Article.create!
Article.first.people.create!
and hopefully to be able to access it the other way afterwards by
Person.first.articles
Unfortunately I get an error when I try to add a person this way:
Article.first.people.create!
NameError: uninitialized constant Article::person
.../base.rb:1199:in `compute_type'
.../reflection.rb:162:in `klass'
.../association_collection.rb:157:in `transaction'
.../has_many_through_association.rb:41:in `create_record'
.../has_many_through_association.rb:13:in `create!
Any help would be very much appreciated I've tried many alternatives but with no success.
I actually just had to some something similar to this recently. It looks like most of your code is right although in mine for the first section I would try changing do this:
class Article < ActiveRecord::Base
has_many :article_tags
has_many :people, :through => :article_tags, :source => :taggable, :source_type => "Person"
end
Also you can't do: Article.first.people.create({:name => "Tim"})
You would have to assign it to a variable first:
article = Article.first
article.people.create({:name => "Tim"})
Let me know if this works for you. I just skimmed through. If it doesn't i can double check my code again and see if there are any other differences.