rails activerecord column query - ruby

I am new to Ruby on Rails.
I get a simple table whose name is Loadtest.
The table have two attributes which are: testname, exectime.
The table may looks like this :
\-------------------------
testname | exectime |
test A | xx-xx-xx |
test B | xx-xx-xx |
\--------------------------
I want to get all the entries under testname, such as ["test A", "test B"]. How could I achieve this?
I could use Loadtest.find(:all) to get all the entries in the table and write some codes to form the testname array. But is there any direct method like Loadtest.column[:testname]?
Thanks for your time!

Yes, there is pluck method.
Loadtest.pluck(:testname)

Related

Custom fields design for multiclient application

I have a question releated to application design. I have a ecommerce application which is used by 9 clients. Every client has the same copy of application with different frontend template. App is designed under laravel and it's updating on every customer server to keep up-to-date. So every app have the same backend("engine"), same database design etc.
Problem is that two of the clients wants a custom fields to for CRUD pages. With current update mechanism every client will get those fields which is not what i want.
I've been thinking about adding separate table to database to keep there a configuration of all fields - like a map of table columns. So when app is used controller will call configuration table to get list of fields and foreach them in view.
+---+---------------+-------------------+------------+
|id |controller | field_name |field_type |
+---+---------------+-------------------+------------+
| 1 | products | price_retail | integer |
| 2 | manufacturers | name | varchar |
| 3 | manufacturers | logo | varchar |
| 4 | manufacturers | custom_for_client | integer |
+---+---------------+-------------------+------------+
Is it a valid - good idea?
Without knowing exactly what you plan to do with these "fields", I can only make suggestions.
Have you considered the use of a json column to store data for fields that aren't applicable to all users?
Database Migration
...
$table->json('meta')->nullable();
...
Model
...
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
...
'meta' => 'array',
...
];
...
You can then access the "fields" within this json object like so:
$model->meta['column'];
or iterate over then like so:
collect($model->meta)->each(function ($column) {});
https://laravel.com/docs/7.x/eloquent-mutators#array-and-json-casting

Doctrine inner join three tables

I'm trying to get Posts by Tags in Symfony 4 with Doctrine. I have three tables like this:
Post
------------------------------
| id | title | content | ... |
------------------------------
Tag
-------------
| id | name |
-------------
TagPost (which makes the association between tags and posts)
--------------------
| tag_id | post_id |
--------------------
There can be several tags by posts and a tag can be used for several posts, that's why I use an association table.
I already succeeded to get it but only with raw sql, I have tried multiple times with the query builder and no way to get it. Any advices ?
The query (working):
"SELECT post.id, post.title, post.author_id, post.content, post.datetime,
post.tile FROM post
INNER JOIN tag_post ON post.id = tag_post.post_id
INNER JOIN tag ON tag_post.tag_id = tag.id
WHERE tag.id = " . $tag_id;
Assuming you're writing this inside a method in your PostRepository (https://symfony.com/doc/3.3/doctrine/repository.html), you'd write:
$qb = $this->createQueryBuilder('post')
->select('post.id, post.title, post.author_id, post.content, post.datetime, post.tile')
->innerJoin('post.tag', 't')
->where('t.id = :tagid')
->setParameter('tagid', $tag_id)
;
$result = $qb->getQuery()->getResult();
Several things to note:
The createQueryBuilder method is not exactly the same in a Repository and in an EntityManager. The EntityManager one needs a ->from() method, while the Repository one guesses the 'from' table and takes instead just a constructor argument for the alias.
The field names, like 'id', 'author_id', 'datetime' etc should not be the names of the fields in your database, but the names of the properties of your doctrine entities. They might be the same, but they're probably camelCase instead of snake_case (e.g., 'authorId'), or they could be completely different. Check your entities to make sure.
Similarly, I'm assuming that the $post entities have a $tag field properly defined via doctrine as a ManyToMany relation. If that's the case, Doctrine will know on its own how to join that property by its name, so that the ->innerJoin method will only need one additional parameter: the alias. If you could include your entities definitions, that would help troubleshoot any additional problems.
Is post.tile (at the end of the SELECT clause) on purpose or is it a misspelling of post.title?

Laravel 4: one to many by on multiple columns?

I'm making a table that essentially maps rows in a table to rows in another table where the structures are as follows:
|--- Words --| |- Synonyms -|
|------------| |------------|
| id | | id |
| en | | word_id |
| ko | | synonym_id |
| created_at | | created_at |
| updated_at | | updated_at |
|------------| |------------|
Now then, I know I can essentially have the words model have many Synonyms through a function like:
public function synonyms()
{
return $this->hasMany('Synonym');
}
No problem, but this method always gets it by the the word_id, and I would like to get it from word_id OR synonym_id that way I don't have to make multiple entries in the DB.
Is there anyway I can do this?
Check laravel docs Eloquent relationships. It would only get word_id because that's the only foreign key I believe.
Also why do you have synonym_id in your Synonyms table?
I believe you are looking for polymorphic relationship.
http://laravel.com/docs/eloquent#polymorphic-relations
I think your best bet is to create a many-to-many relationship with words on itself using the synonyms table as your pivot table.
Add this to your Word model.
public function synonyms()
{
return $this->belongsToMany('Word', 'synonyms', 'user_id', 'synonym_id');
}
Using it:
$word = Word::where('en', '=', 'someword')->first();
foreach($word->synonyms as $synonym) {
// This method would probably return the same word as a synonym of itself so we can skip that iteration.
if($synonym->en == $word->en) {
continue;
}
// Echo the synonym.
echo $synonym->en;
}
I'm a bit confused on you wanting to be able to find synonyms by the word_id or synonym_id but I think if you are using the many-to-many, it won't matter because if you know the synonym, it's still technically just a word, and you'd do the exact same thing.

Propel ORM - One-to-many relationship with parent name

Is it possible to create a parent name field into one-to-many relationship in Propel ORM.
This type of relationship uses in CRM systems.
Just imagine that we have a Task List. So, we created a Task #1 and related it to a Project.
Task #2 is related to Account (e.g. create a contract).
Task #3 is related to Bug Tracker (e.g. fix a bug).
So, we have the following relationships:
task_name | parent_name | parent_id
--------------------------------------------------
Start a project | Project | <project_id>
Create a contract | Account | <account_id>
Fix a bug | Bug Tracker | <bug_id>
Is it possible to implement in Propel. If no, could you recommend me another ORM with this feature.
The main purpose is to get a list of records with all relationship values.
For my example, it should look like (in JSON):
{
"Task_0":{"Id":1,"Name":"Start a project","ParentId":1,"ParentName":"Project","Project":{"Id":1,"Name":"Project-1","Tasks":{"Task_0":"*RECURSION*"}}},
"Task_1":{"Id":1,"Name":"Create a contract","ParentId":1,"ParentName":"Account","Account":{"Id":1,"Name":"Account-1","Tasks":{"Task_0":"*RECURSION*"}}},
"Task_2":{"Id":1,"Name":"Fix a bug","ParentId":1,"ParentName":"Bug","Bug":{"Id":1,"Name":"Bug-1","Tasks":{"Task_0":"*RECURSION*"}}}
}
Does anyone help me?
The output you have shown looks as if the toArray function has been used on the Propel objects and then the json_encode function. This should work if you define foreign keys mutually in Propel's schema.xml.
Since project tasks, account tasks and bug tracker tasks all have something in common, they all are tasks :), I would organize them as sub classes of a more general task entity.
You will end up with a collection of tables like this:
Table "task"
id | name
------------------------
1 | Start a project
2 | Create a contract
3 | Fix a bug
4 | Start another project
5 | Fix another bug
---------------------------------------
Table "bugtrack_task"
id | id_task
---------------
1 | 3
2 | 5
---------------------------------------
Table "project_task"
id | id_task
---------------
1 | 1
2 | 4
---------------------------------------
Table "account_task"
id | id_task
---------------
1 | 2
In the end, you would define a view in the schema.xml. This could look something like this:
<table name="view_task" phpName="ViewTask" skipSql="true" readOnly="true" description="All my tasks together for display">...</table>
Note that the skipSql attribute has been set to true. This will skip this view table when generating the SQL code. Propel will generate the classes for you but won't touch your database. You can now manually define the view yourself putting into it whatever you desire.
Of course you'd have to put some effort into creating this view but it pays off as you will be able to use the Propel classes like so for instance:
$tasks = ViewTask::create()->find();
$result = array();
foreach($tasks as $task) {
$result[] = $task->toArray();
}
return json_encode($result);
This isn't a complete answer but I hope you see the idea! Good luck :-)

one to many save, codeigniter DataMapper

Working on a site where a user can add videos. Each video can be in many sections. It can also have many questions. Video has a one-to-many relationships with both the question and section classes.
I'm getting the section and video classes like this:
$s = new Section();
$s->where('section', $this->post->section)->get();
then saving like this:
$v->save($u, $s, $q);
where $v is a video object, $u is a user object and $q is a question object.
I want to allow the user to POST multiple questions and sections. How do I save those relationships. Should $s and $q be arrays of objects?
I am not 100% sure that I understand what you mean but yes yu can save multiple relations at the same time.
Like this:
$s = new Section();
$s->where_in('section', $array_with_sections_ids)->get();
$v->save(array($u, $s->all, $q));
You use different tables in your database. Like Video, Question and VideoQuestion where you store the video ID with the different Question id's
Then VideoExample would look like:
| video_id | question_id |
--------------------------
| 1 | 1 |
| 1 | 5 |
...
for inserting this data, first insert the video and get its ID with
$videoId = $this->db->insert_id()
Do the same for your question and you've got your ID's ;)
The same for the other tables and you're done. Good Luck!

Resources