Ruby 3.0.1 and Rails 6.1.3.2. Active Record has_many and has_one - ruby-on-rails-6

I have a legacy database/tables. How do I specify the keys for the has_many and has_one relationship?
Parent:
PRN_AUTO_KEY (is the ID field)
Child:
CHL_AUTO_KEY (is the ID field)
PRN_AUTO_KEY (is the foreign key field)
Not sure how to do this

I think you are talking about the general One to Many associations.
For example: Reference.
Have a look at this it's pretty detailed.
class Author < ApplicationRecord
has_many :books, dependent: :destroy
end
class Book < ApplicationRecord
belongs_to :author
end
So, the table structure would be like this:
Authors
id
col1
col2
1
...
...
2
...
...
3
...
...
Books
id
author_id
col2
1
1
...
2
1
...
3
2
...

For me, as stated, the ID field is not ID. So I would have to do the following:
class Author < ApplicationRecord::Base
set_primary_key :ath_auto_key
has_many :books, dependent: :destroy
end
class Book < ApplicationRecord::Base
set_primary_key :bks_auto_key
belongs_to :author
end

Related

Rails Migration : How to change the "foreign_key: true" to foreign_key: {to_table: ... } of a certain references column

i am kind of new to rails and My question is that how can i change a certain "foreign_key: true" to foreign_key: {to_table: ... } in a certain references column.
Example_FROM:
class CreateExamples < ActiveRecord::Migration[5.2]
def change
create_table :examples do |t|
t.references :test, foreign_key: true
t.timestamps
end
end
end
Example_TO:
class CreateExamples < ActiveRecord::Migration[5.2]
def change
create_table :examples do |t|
t.references :test, foreign_key: {to_table: :things}
t.timestamps
end
end
end
a simple line of code on how to do this would be appreciated.
So i found a solution. i just simply deleted the columns of the foreign keys with remove_column and then added the new version of foreign keys with add_reference.
Hope it helps anyone who have the same problem :)

Elixir recursion

I have a group, which I can attach to other modules. The group can have a parent group:
schema "groups" do
field :name, :string
field :deleted, :boolean
belongs_to :parent, Group
has_many :users_groups, UserGroup, foreign_key: :group_id
timestamps()
end
Via user_groups i Can attach users. Now I want to filter, if the user is allowed to see the attached module. I made a check, to see if the user is inside the attached group:
def get_visible_module(module, user_id) do
case module.group do
nil -> module
_ ->
case module.group.users_groups do
nil -> module
_ ->
val = Enum.filter(module.group.users_groups, fn(x)->
x.user_id == user_id
end)
case val do
[] ->
case false do
true -> module
false -> nil
end
_ -> module
end
end
end
end
This may be not the best code, but I am still learning, so improvements to this part are also welcome :)
Now my problem is to add a recursion to check, if the user_id is attached via user_group to a group, which is attached via the parent_id. I am stucked at this point. For the understanding: A module has a group attached. Only the user in the group or in the group attached via parent_id are allowed to see the module. Groups are structered as a tree, so I need to eager load the parent group and check if the user_group contains the user and check every parent-group too.
Hope it is understandable.
THX
Here is a rough skeleton which adapts the naming of your source code. It should give you an idea on how to make a recursion in elixir.
# Exit case when a module has no more parent
def get_visible_module(module, nil, user_id) do
user_in_groups?(module.group.users_groups, user_id)
end
# Case when the module has a parent_id
def get_visible_module(module, parent_id, user_id) do
# check the groups for user_id permission followed by the recusive part
user_in_groups?(module.group.users_groups, user_id) and get_visible_module(parent_module, parent_module.parent_id, user_id)
end
# checks if the user is in the group
defp user_in_groups?(users_groups, user_id) do
# check if the use is in one of the groups
true
end
As #bla already mentioned you should try to use pattern matching to clean up your code and reduce the nesting level of your code.

Symfony order by the content of a specific field

I want to sort data in repository based on the content of a specific field
For example i have an entity person with the fields role,fistName and lastName.
I would like to sort using ->orderBy('p.role', ???) and get a list ordered based on this order : professors then directors then teachers and at last students .
Example of my database:
Wanted result:
Ps: i can not use ASC or DESC since my sorting order is neither ASC nor DESC;
it is a custom order
Very strage scenario, you could use a CASE statement in order to assing a custom value for each fields then sort on him.
You could use the HIDDEN keyword.
As example take a look at this DQL:
SELECT p, CASE
WHEN p.role = "professor" THEN 1
WHEN p.role = "director" THEN 2
WHEN p.role = "teacher" THEN 3
WHEN p.role = "student" THEN 4
ELSE 99 END
AS HIDDEN mySortRule
FROM Bundle\Entity\Person p
ORDER BY mySortRule ASC
Hope this help

One to many association. Undefined method

I have a table countries and a model Country with the following columns id,cc_fips,cc_iso,tld, country_name with all the countries in the world listed.
I have a table users and model User with columns id, name, age...........
Every user has one country but one country has many users.
I want to create a table in the middle where i will register columns country_id, user_id.
A one to many association.
I named the table countryforusers and the model Countryforuser.
My migration to create the model:
class CreateCountryforusers < ActiveRecord::Migration
def change
create_table :countryforusers, {:id => false} do |t|
t.integer "country_id"
t.string "user_id", :null => false, :default => ""
t.timestamps
end
add_index("countryforusers","country_id")
end
end
My model User:
class User < ActiveRecord::Base
has_many :images
belongs_to :countryforuser
end
My model Countryforuser:
class Countryforuser < ActiveRecord::Base
has_many :users
end
However it doesn't work.
I have all the time a message undefined method `countryforusers' when trying to add one user for a country.
What am i doing wring?
Thank you very much.
Although each user has one country and one country many users, i had to use a many to many association, if i would put a join table in the middle. So the word many to many is a bit confusing this time.

Rails associations and Thinking Sphinx Indexing to refactor search method in controller

I'm working with a old database and drawing blank on how to set up the association and index it with Thinking Sphinx. I want to index the People and Group's skill.
I have Users. Users can create People and Groups. People and Groups have a single skill through Sharing_Skill.
people and groups tables: ID field, Name field
sharings_skills table: ID field, Skill_ID field, Marker_ID(which is the person/group_id), Marker_Type ("Group" or "Person")
skills table: ID field, Name field
How do I setup the rails association and index the skills of the person or group in the Person model or Group model.
my main goal is to refactor my search by indexing the person skills in the person model and searching the name, tags and skills together, instead of searching skills, sharing_skills and people separate like this:
This is in my Person model.
class Person < ActiveRecord::Base
acts_as_taggable
acts_as_taggable_on :tags
attr_accessible :name, :tag_list
validates_presence_of :name
belongs_to :marker_image, :class_name => "Photo", :foreign_key => "marker_image_id"
belongs_to :user
extend FriendlyId
friendly_id :name, use: [:slugged, :history]
define_index do
indexes name
indexes tag_taggings.tag(:name), :as => :tags
has :id
has created_at
end
This is in my Search Controller
#PERSON SEARCH
if params[:marker_type].nil? or params[:marker_type].empty? or params[:marker_type] == "Person"
#SEARCH NAME, TAGS, (Need to fix skills)
conditions = {}
%w(name tags).each do |i|
i = i.to_sym
next unless params[i]
conditions[i] = params[i]
end
person = Person.search_for_ids(params[:search], :conditions => conditions, :per_page => 999999)
if !person.empty?
person_ids << person
end
#SEARCH SKILLS IN PERSON MODEL
skills = Skill.search_for_ids(params[:search], :per_page => 99999)
check_skills_available_persons = SharingsSkill.search(:conditions => {:marker_type => 'Person'}, :with => {:skill_id => skills}, :per_page => 99999)
if !check_skills_available_persons.empty?
check_people_by_skills = Person.search(:with => {:id => check_skills_available_persons.collect{|x|x.marker_id}})
if !check_people_by_skills.empty?
check_people_by_skills.each do |p_skill|
person_ids << p_skill.id
end
end
end
end
Watched through "Rails 3 Essential Training" chapter on associations and read through Rails guides write up on Active Record associations. Before I was searching the name, the tags, the skill individually and collecting the ID's in succession. With the proper polymorphic association you can search all the parameters in a single search method.
Person Model.
has_one :sharing_skill, :as => :marker, :conditions => ['marker_type = ?', 'Person']
has_one :skill, :through => :sharing_skill
define_index do
indexes name
indexes tag_taggings.tag(:name), :as => :tags
indexes skill(:name), :as => :skill
has :id
has created_at
end
Group Model.
has_one :sharing_skill, :as => :marker, :conditions => ['marker_type = ?', 'Group']
has_one :skill, :through => :sharing_skill
define_index do
indexes name
indexes tag_taggings.tag(:name), :as => :tags
indexes skill(:name), :as => :skill
has :id
has created_at
end
Sharing_skill.model
belongs_to :marker, :polymorphic => true
belongs_to :skill
Skill model.
has_one :sharing_skill
has_one :person, :through => :sharing_skill, :source => :marker
has_one :group, :through => :sharing_skill, :source => :marker
Search Controller.
#SEARCH NAME, TAGS, AND SKILL
conditions = {}
%w(name tags skill).each do |i|
i = i.to_sym
next unless params[i]
conditions[i] = params[i]
end
person = Person.search(params[:search], :conditions => conditions, :per_page => 999999)

Resources